package net.thucydides.core.statistics.model;
import com.google.common.collect.ImmutableList;
import net.thucydides.core.model.TestResult;
import java.util.List;
import static ch.lambdaj.Lambda.select;
import static org.hamcrest.Matchers.is;
/**
* A summary of statistics related to a particular set of tests.
* First, obtain a set of statistics using the HibernateTestStatisticsProvider class. For example, you could
* obtain statistics for a particular test outcome like this:
* <pre>
* <code>
* TestStatistics stats = testStatisticsProvider.statisticsForTests(With.title(testOutcome.getTitle()));
* </code>
* </pre>
* or
* <pre>
* <code>
* TestStatistics stats = testStatisticsProvider.statisticsForTests(With.tag("A story));
* </code>
* </pre>
* Then, you can obtain various statistics about the test (or group of tests):
* <pre>
* <code>
* Double passRateForAllTests = stats.getOverallPassRate();
* Double recentPassRate = stats.getPassRate().overTheLast(5).testRuns();
* </code>
* </pre>
*/
public class TestStatistics {
private final Long totalTestRuns;
private final Long passingTestRuns;
private final Long failingTestRuns;
private final List<TestResult> testResults;
private final List<TestRunTag> tags;
private static final int OVERALL = Integer.MAX_VALUE;
public TestStatistics(Long totalTestRuns,
Long passingTestRuns,
Long failingTestRuns,
List<TestResult> testResults,
List<TestRunTag> tags) {
this.totalTestRuns = totalTestRuns;
this.passingTestRuns = passingTestRuns;
this.failingTestRuns = failingTestRuns;
this.tags = ImmutableList.copyOf(tags);
this.testResults = ImmutableList.copyOf(testResults);
}
public Long getTotalTestRuns() {
return totalTestRuns;
}
public Long getPassingTestRuns() {
return passingTestRuns;
}
public Long getFailingTestRuns() {
return failingTestRuns;
}
public Double getOverallPassRate() {
if (totalTestRuns > 0) {
return (double) passingTestRuns / (double) totalTestRuns;
} else {
return 0.0;
}
}
public List<TestRunTag> getTags() {
return tags;
}
/**
* Find the pass rate over a given number of tests
* <pre>
* <code>
* Double recentPassRate = stats.getPassRate().overTheLast(5).testRuns();
* </code>
* </pre>
* @return the pass rate over a given number of tests
*/
public PassRateBuilder getPassRate() {
return new PassRateBuilder(OVERALL);
}
public ResultCountBuilder countResults() {
return new ResultCountBuilder(OVERALL);
}
public class PassRateBuilder {
int testRunsOverPeriod;
public PassRateBuilder(int testRunsOverPeriod) {
this.testRunsOverPeriod = testRunsOverPeriod;
}
public PassRateBuilder overTheLast(int number) {
return new PassRateBuilder(number);
}
public double testRuns() {
int successfulRecentTestRuns = countSuccessfulTestRunsInLast(testRunsOverPeriod, testResults);
int eligableTestRunCount = (testResults.size() < testRunsOverPeriod) ? testResults.size() : testRunsOverPeriod;
if (eligableTestRunCount > 0) {
return (successfulRecentTestRuns * 1.0) / (eligableTestRunCount * 1.0);
} else {
return 0.0;
}
}
private int countSuccessfulTestRunsInLast(int testRunCount, List<TestResult> testResults) {
List<TestResult> eligableTestResults = mostRecent(testRunCount, testResults);
List<TestResult> successfulTestResults = select(eligableTestResults, is(TestResult.SUCCESS));
return successfulTestResults.size();
}
private List<TestResult> mostRecent(int testRunsOverPeriod, List<TestResult> testResults) {
int eligableCount = eligableTestResultSize(testResults, testRunsOverPeriod);
return testResults.subList(0, eligableCount);
}
private int eligableTestResultSize(List<TestResult> testResults, int testRunsOverPeriod) {
return (testRunsOverPeriod > testResults.size()) ? testResults.size() : testRunsOverPeriod;
}
}
public class ResultCountBuilder {
int testRunsOverPeriod;
public ResultCountBuilder(int testRunsOverPeriod) {
this.testRunsOverPeriod = testRunsOverPeriod;
}
public ResultCountBuilder overTheLast(int number) {
return new ResultCountBuilder(number);
}
public int whereTheOutcomeWas(TestResult testResult) {
return countTestRunsByResultInLast(testResult, testRunsOverPeriod, testResults);
}
private int countTestRunsByResultInLast(TestResult testResult, int testRunCount, List<TestResult> testResults) {
List<TestResult> eligableTestResults = mostRecent(testRunCount, testResults);
List<TestResult> successfulTestResults = select(eligableTestResults, is(testResult));
return successfulTestResults.size();
}
private List<TestResult> mostRecent(int testRunsOverPeriod, List<TestResult> testResults) {
int eligableCount = eligableTestResultSize(testResults, testRunsOverPeriod);
return testResults.subList(0, eligableCount);
}
private int eligableTestResultSize(List<TestResult> testResults, int testRunsOverPeriod) {
return (testRunsOverPeriod > testResults.size()) ? testResults.size() : testRunsOverPeriod;
}
}
}