Kotest 통계(Statistics)

때로는 생성기가 예상한 방식으로 구성되었는지 확인하기 위해 Kotest에서 생성되는 값의 유형을 알고 싶을 수 있다.

통계(Statistics)

때로는 제너레이터가 원하는 방식으로 구성되었는지 확인하기 위해 Kotest에서 생성되는 값의 유형을 알고 싶을 수 있다. 속성 테스트 통계는 이러한 요구를 충족하도록 설계되었다.

수집 함수는 통계의 시작점이며 값의 범주를 계산하는 데 사용된다. 이 함수는 속성 테스트 내에서 증가시키려는 범주로 호출하여 사용한다.

예를 들어 BigDecimal이 사용하는 RoundingMode 값에 대한 통계를 수집하고 싶다고 가정해 봅시다. 평소처럼 checkAll을 호출하여 반올림 모드를 수집 함수에 전달한다.

checkAll(Arb.enum<RoundingMode>(), Arb.bigDecimal()) { mode, decimal ->
  collect(mode)
  // test here
}

이제 테스트가 완료되면 Kotest는 테스트 이름과 각 카테고리의 개수/백분율을 출력한다:

Statistics: [collecting stats] (1000 iterations, 1 args)

HALF_DOWN                                                     142 (14%)
HALF_UP                                                       141 (14%)
CEILING                                                       132 (13%)
FLOOR                                                         122 (12%)
UP                                                            119 (12%)
UNNECESSARY                                                   119 (12%)
HALF_EVEN                                                     118 (12%)
DOWN                                                          107 (11%)

사용하는 카테고리는 열거형일 필요는 없다. 모든 객체가 될 수 있으며, 더 많은 제어를 원하면 조건부로 래핑할 수 있다. 예를 들어

checkAll(Arb.int()) { k ->
  when {
    k % 2 == 0 -> collect("EVEN")
    else -> collect("ODD")
  }
  // test here
}

레이블(Labels)

때로는 직교 통계 집합이 필요할 수 있다. 예를 들어 간단한 숫자 테스트의 경우 특정 비율은 짝수이고 특정 비율은 음수인지 확인하고 싶을 수 있다. 한 가지 방법은 EVEN_POS, EVEN_NEG, ODD_POS, ODD_NEG를 사용하는 것이다:

checkAll(Arb.int()) { k ->
  when {
    k > 0 && k % 2 == 0 -> collect("EVEN_POS")
    k % 2 == 0 -> collect("EVEN_NEG")
    k > 0 -> collect("ODD_POS")
    else -> collect("ODD_NEG")
  }
  // test here
}

이렇게 하면 하나의 출력 세트가 제공된다:

EVEN_POS                                                       142 (27%)
EVEN_NEG                                                       141 (23%)
ODD_POS                                                        132 (24%)
ODD_NEG                                                        122 (26%)

그러나 조합이 많아지면 다루기 어려워지므로 Kotest는 레이블이 지정된 통계를 지원한다. 이를 별개의 통계 집합으로 생각할 수 있다. 레이블을 사용하려면 수집 메서드에 첫 번째 인수로 레이블 이름을 전달하기만 하면 된다.

checkAll(Arb.int()) { k ->
  when {
    k % 2 == 0 -> collect("even_odd", "EVEN")
    else -> collect("even_odd", "ODD")
  }
  when {
    k > 0 -> collect("pos_neg", "POS")
    else -> collect("pos_neg", "NEG")
  }
  // test here
}

이제 Kotest는 제목에 레이블 이름이 포함된 여러 통계 집합을 출력한다:

Statistics: [collecting labelled stats] (1000 iterations, 1 args) [even_odd]

ODD                                                           520 (52%)
EVEN                                                          480 (48%)


Statistics: [collecting labelled stats] (1000 iterations, 1 args) [pos_neg]

NEG                                                           527 (53%)
POS                                                           473 (47%)

보고서 모드

기본적으로 모든 프로퍼티 테스트에 대한 통계가 출력된다. 글로벌 구성 개체 PropertyTesting을 사용하여 구성할 수 있는 네 가지 모드가 있다.

가능한 옵션은 다음과 같다:

Mode Function
PropertyTesting.statisticsReportMode = StatisticsReportMode.OFF disable all statistics reporting
PropertyTesting.statisticsReportMode = StatisticsReportMode.OFF enables all statistics reporting
PropertyTesting.statisticsReportMode = StatisticsReportMode.SUCCESS output statistics only on successful tests
PropertyTesting.statisticsReportMode = StatisticsReportMode.FAILED output statistics only on failed tests

통계의 적용 범위 확인

프로그래밍 방식으로 특정 값이 생성되고 있다고 주장하려면 충족해야 하는 제약 조건을 지정할 수 있다.

예를 들어, 앞의 반올림 예제에서 withCoveragePercentages를 사용하여 최소 10%의 입력이 HALF_DOWN을 커버하고 10%가 FLOOR를 커버하는지 확인할 수 있다:

withCoveragePercentages(mapOf(RoundingMode.HALF_DOWN to 10.0, RoundingMode.FLOOR to 10.0)) {
  checkAll(Arb.enum<RoundingMode>(), Arb.bigDecimal()) { mode, decimal ->
    collect(mode)
    // use the mode / decimal
  }
}

백분율이 아닌 절대 숫자로 확인하려면 withCoverageCounts를 사용하면 된다:

withCoverageCounts(mapOf(RoundingMode.HALF_DOWN to 75, RoundingMode.FLOOR to 75)) {
  checkAll(Arb.enum<RoundingMode>(), Arb.bigDecimal()) { mode, decimal ->
    collect(mode)
    // use the mode / decimal
  }
}

사용자 지정 보고서

통계 보고서의 자체 인스턴스를 사용하여 보고서 형식을 사용자 지정하거나 원시 데이터에서 보고서를 생성할 수 있다. 이는 글로벌 구성 개체 PropertyTesting을 통해 구성된다.

예를 들어

object MyStatisticsReporter : object : StatisticsReporter { ... }
PropertyTesting.statisticsReporter = MyStatisticsReporter

참조




최종 수정 : 2024-04-21