Browse Source

PityTest: Duration measurement for TestUnits

pull/2/head
heck 5 years ago
parent
commit
1acc5ad51b
  1. 3
      test/java/foundation/pEp/pitytest/Makefile.conf
  2. 20
      test/java/foundation/pEp/pitytest/StopWatch.java
  3. 8
      test/java/foundation/pEp/pitytest/TestResult.java
  4. 2
      test/java/foundation/pEp/pitytest/TestState.java
  5. 6
      test/java/foundation/pEp/pitytest/TestSuite.java
  6. 168
      test/java/foundation/pEp/pitytest/TestUnit.java
  7. 2
      test/java/foundation/pEp/pitytest/utils/TestUtils.java

3
test/java/foundation/pEp/pitytest/Makefile.conf

@ -13,5 +13,6 @@ JAVA_CLASSES_PITYTEST= \
utils/TestUtils.class \ utils/TestUtils.class \
utils/Pair.class \ utils/Pair.class \
TestState.class \ TestState.class \
TestResult.class TestResult.class \
StopWatch.class

20
test/java/foundation/pEp/pitytest/StopWatch.java

@ -0,0 +1,20 @@
package foundation.pEp.pitytest;
import java.time.Duration;
public class StopWatch {
private long timeStart = 0;
private long timeEnd = 0;
private Duration duration = null;
public StopWatch(Runnable lambda) {
timeStart = System.nanoTime();
lambda.run();
timeEnd = System.nanoTime();
duration = Duration.ofNanos(timeEnd - timeStart);
}
public Duration getDuration() {
return duration;
}
}

8
test/java/foundation/pEp/pitytest/TestResult.java

@ -1,8 +0,0 @@
package foundation.pEp.pitytest;
public enum TestResult {
UNEVALUATED,
SKIPPED,
SUCCESS,
FAILED;
}

2
test/java/foundation/pEp/pitytest/TestState.java

@ -7,6 +7,6 @@ public enum TestState {
FAILED, FAILED,
STARTING, STARTING,
CTX_INIT, CTX_INIT,
CTX_INIT_FAILED, CTX_FAIL,
RUNNING; RUNNING;
} }

6
test/java/foundation/pEp/pitytest/TestSuite.java

@ -98,9 +98,9 @@ public class TestSuite {
int failedCount = 0; int failedCount = 0;
int successCount = 0; int successCount = 0;
for (TestUnit t : tests) { for (TestUnit t : tests) {
if (t.getResult() == TestResult.SKIPPED) skippedCount++; if (t.getResult() == TestState.SKIPPED) skippedCount++;
if (t.getResult() == TestResult.FAILED) failedCount++; if (t.getResult() == TestState.FAILED) failedCount++;
if (t.getResult() == TestResult.SUCCESS) successCount++; if (t.getResult() == TestState.SUCCESS) successCount++;
} }
failedCount = failedCount + skippedCount; failedCount = failedCount + skippedCount;

168
test/java/foundation/pEp/pitytest/TestUnit.java

@ -3,30 +3,38 @@ package foundation.pEp.pitytest;
import foundation.pEp.pitytest.utils.TestUtils; import foundation.pEp.pitytest.utils.TestUtils;
import static foundation.pEp.pitytest.TestLogger.*; import static foundation.pEp.pitytest.TestLogger.*;
import static foundation.pEp.pitytest.utils.TestUtils.TermColor; import static foundation.pEp.pitytest.utils.TestUtils.*;
import static foundation.pEp.pitytest.utils.TestUtils.colorString;
import java.text.DecimalFormat;
import java.time.Duration;
import java.util.function.Consumer; import java.util.function.Consumer;
//Automatically get added to the default TestSuite always // Automatically gets added to the default TestSuite always
//Can be added to any nr of TestSuites // Can be added to any nr of TestSuites
public class TestUnit<T extends TestContextInterface> implements Runnable { public class TestUnit<T extends TestContextInterface> implements Runnable {
private String testUnitName = "default test unit"; private String testUnitName = "default test unit";
private T ctx; private T ctx;
private Consumer<T> lambda; private Consumer<T> lambda;
private TestResult result = TestResult.UNEVALUATED; private TestState result = TestState.UNEVALUATED;
private TestState state = TestState.UNEVALUATED; private TestState state = TestState.UNEVALUATED;
private Throwable lastException; private Throwable lastException;
private Duration testDuration = null;
private boolean verboseMode = true; private boolean verboseMode = true;
private TermColor testColor = TermColor.CYAN; private TermColor testColor = TermColor.CYAN;
// Defaults (line width 80) // Defaults (line width 80)
private int logFmtTestNameLen = 35; // fixed width
private int logFmtCtxNameLen = 25; private int logFmtPadding = 4;
private int logFmtMsgLen = 12; private int logFmtMsgLen = 12;
private int logFmtTestDuration = 14;
private int lineWidthMin = logFmtPadding + logFmtMsgLen + logFmtTestDuration + 20;
// dynamic
private int logFmtTestNameLen = 32;
private int logFmtCtxNameLen = 20;
public TestUnit(String name, T context, Consumer<T> lambda) { public TestUnit(String name, T context, Consumer<T> lambda) {
this.testUnitName = name; this.testUnitName = name;
@ -52,7 +60,7 @@ public class TestUnit<T extends TestContextInterface> implements Runnable {
this.testColor = testColor; this.testColor = testColor;
} }
public TestResult getResult() { public TestState getResult() {
return result; return result;
} }
@ -73,93 +81,80 @@ public class TestUnit<T extends TestContextInterface> implements Runnable {
public void run() { public void run() {
TestUtils.standardOutErrEnabled(verboseMode); TestUtils.standardOutErrEnabled(verboseMode);
if (ctx.isUninitializable()) { if (ctx.isUninitializable()) {
setTestState(TestState.CTX_INIT_FAILED); setTestState(TestState.CTX_FAIL);
TestUtils.standardOutErrEnabled(true); TestUtils.standardOutErrEnabled(true);
return; } else {
} try {
try { setTestState(TestState.STARTING);
setTestState(TestState.STARTING); // Init the Context if not already done
// Init the Context if not already done if (!ctx.isInitialized()) {
if (!ctx.isInitialized()) { //Context init problems need to throw to fail
//Context init problems need to throw to fail try {
try { setTestState(TestState.CTX_INIT);
setTestState(TestState.CTX_INIT); setTermColor(testColor);
setTermColor(testColor); ctx.init();
ctx.init(); setTermColor(TermColor.RESET);
setTermColor(TermColor.RESET); } catch (Throwable t) {
} catch (Throwable t) { lastException = t;
lastException = t; setTermColor(TermColor.RESET);
setTermColor(TermColor.RESET); ctx.setUninitializable(true);
setTestState(TestState.CTX_INIT_FAILED); setTestState(TestState.CTX_FAIL);
TestUtils.standardOutErrEnabled(true); TestUtils.standardOutErrEnabled(true);
return; return;
}
ctx.setInitialized(true);
} }
ctx.setInitialized(true); //tests need to throw to fail
setTestState(TestState.RUNNING);
setTermColor(testColor);
testDuration = new StopWatch(() -> {
lambda.accept(ctx);
}).getDuration();
setTermColor(TermColor.RESET);
setTestState(TestState.SUCCESS);
} catch (Throwable t) {
lastException = t;
setTermColor(TermColor.RESET);
setTestState(TestState.FAILED);
TestUtils.standardOutErrEnabled(true);
return;
} }
//tests need to throw to fail
setTestState(TestState.RUNNING);
setTermColor(testColor);
lambda.accept(ctx);
setTermColor(TermColor.RESET);
setTestState(TestState.SUCCESS);
} catch (Throwable t) {
lastException = t;
setTermColor(TermColor.RESET); setTermColor(TermColor.RESET);
setTestState(TestState.FAILED);
TestUtils.standardOutErrEnabled(true); TestUtils.standardOutErrEnabled(true);
return;
} }
setTermColor(TermColor.RESET);
TestUtils.standardOutErrEnabled(true);
} }
private void setTestState(TestState s) { private void setTestState(TestState s) {
state = s; state = s;
switch (state) { switch (state) {
case UNEVALUATED: { case UNEVALUATED:
setTestResult(TestResult.UNEVALUATED); case SKIPPED:
break; case SUCCESS:
}
case SKIPPED: {
setTestResult(TestResult.SKIPPED);
break;
}
case SUCCESS: {
setTestResult(TestResult.SUCCESS);
break;
}
case FAILED: { case FAILED: {
setTestResult(TestResult.FAILED); setTestResult(s);
break; break;
} }
case STARTING:
case CTX_INIT: case CTX_INIT:
case STARTING:
case RUNNING: { case RUNNING: {
logH1(makeLogString(state.toString())); logH1(makeLogString());
break; break;
} }
case CTX_INIT_FAILED: { case CTX_FAIL: {
logH1(makeLogString(state.toString())); setTestResult(TestState.SKIPPED);
setTestResult(TestResult.SKIPPED); // logH1(makeLogString());
break; break;
} }
} }
} }
private void setTestResult(TestResult r) { private void setTestResult(TestState r) {
assert (r == TestState.SKIPPED || r == TestState.FAILED || r == TestState.SUCCESS || r == TestState.UNEVALUATED ): "PityTest Internal: illegal result value '" + r +"'";
result = r; result = r;
String resultStr = r.toString();
if(r != TestResult.SUCCESS) {
resultStr = colorString(resultStr, TermColor.RED);
} else {
resultStr = colorString(resultStr, TermColor.GREEN);
}
TestUtils.standardOutErrEnabled(true); TestUtils.standardOutErrEnabled(true);
logH1(makeLogString(resultStr)); logH1(makeLogString());
if( r != TestResult.SUCCESS) { if (result == TestState.FAILED || result == TestState.CTX_FAIL) {
log("ERROR: " + getLastException().toString()); log("ERROR: " + getLastException().toString());
} }
if (verboseMode) logRaw("\n\n"); if (verboseMode) logRaw("\n\n");
@ -167,16 +162,39 @@ public class TestUnit<T extends TestContextInterface> implements Runnable {
} }
private void logLayout() { private void logLayout() {
logFmtTestNameLen = (int) Math.floor(TestLogger.getMsgWidth() * 0.39); int lineWidth = TestLogger.getMsgWidth();
logFmtCtxNameLen = (int) Math.floor(TestLogger.getMsgWidth() * 0.28); // Fixed sizes
logFmtMsgLen = (int) Math.floor(TestLogger.getMsgWidth() * 0.25); lineWidth -= logFmtPadding;
lineWidth -= logFmtMsgLen;
lineWidth -= logFmtTestDuration;
lineWidth = clip(lineWidth, lineWidthMin, Integer.MAX_VALUE);
// Proportional (dynamic sizes)
logFmtTestNameLen = (int) Math.floor(lineWidth * 0.45);
logFmtCtxNameLen = (int) Math.floor(lineWidth * 0.45);
} }
private String makeLogString(String str) { private String makeLogString() {
String resultStr = state.toString();
if (state == TestState.FAILED) {
resultStr = colorString(resultStr, TermColor.RED);
} else if (state == TestState.SUCCESS) {
resultStr = colorString(resultStr, TermColor.GREEN);
}
String testUnitNameFmtd = TestUtils.padOrClipString(" TEST: '" + testUnitName + "' ", "=", logFmtTestNameLen, TestUtils.Alignment.Left, ".. "); String testUnitNameFmtd = TestUtils.padOrClipString(" TEST: '" + testUnitName + "' ", "=", logFmtTestNameLen, TestUtils.Alignment.Left, ".. ");
String testCtxNameFmtd = TestUtils.padOrClipString(" CTX: '" + ctx.getTestContextName() + "' ", "=", logFmtCtxNameLen, TestUtils.Alignment.Center, ".. "); String testCtxNameFmtd = TestUtils.padOrClipString(" CTX: '" + ctx.getTestContextName() + "' ", "=", logFmtCtxNameLen, TestUtils.Alignment.Center, ".. ");
String strFmtd = TestUtils.padOrClipString(" " + str + " ", "=", logFmtMsgLen, TestUtils.Alignment.Right, ".. "); String strTestDuration = "";
return testUnitNameFmtd + testCtxNameFmtd + strFmtd; if (state == TestState.SUCCESS) {
DecimalFormat f = new DecimalFormat("0.000");
String durationFmtd = f.format(testDuration.toMillis() / 1000.0);
strTestDuration = TestUtils.padOrClipString(" [" + durationFmtd + " sec] ", "=", logFmtTestDuration, TestUtils.Alignment.Right, ".. ");
} else {
strTestDuration = TestUtils.padOrClipString("", "=", logFmtTestDuration, TestUtils.Alignment.Right, ".. ");
}
String strFmtd = TestUtils.padOrClipString(" " + resultStr + " ", "=", logFmtMsgLen, TestUtils.Alignment.Right, ".. ");
return testUnitNameFmtd + testCtxNameFmtd + strTestDuration + strFmtd;
} }
} }

2
test/java/foundation/pEp/pitytest/utils/TestUtils.java

@ -140,7 +140,7 @@ public class TestUtils {
public static String padOrClipString(String str, String padChar, int len, Alignment alignment, String clipMsg) { public static String padOrClipString(String str, String padChar, int len, Alignment alignment, String clipMsg) {
String ret = ""; String ret = "";
int strLen = str.length(); int strLen = str.length();
len += (substringOccurencesCount(str, "\u001B") * 4); len += (substringOccurencesCount(str, "\u001B") * 4.5);
if (strLen <= len) { if (strLen <= len) {
if (alignment == Alignment.Left) { if (alignment == Alignment.Left) {
ret = str + repeatString(padChar, len - strLen); ret = str + repeatString(padChar, len - strLen);

Loading…
Cancel
Save