我想为我们库中的接口提供一个测试套件,以便实现该接口的客户端可以轻松地测试其实现是否符合接口规范。
一个非常简单的例子可能如下所示:
// Library code.
abstract class LibTest(impl: LibInterface) {
@Test
def myTest: Unit = {
assertTrue(impl.getTrue())
}
}
// Client code
class MyTest extends LibTest(new MyInterfaceImpl)
然而,我们需要更多的东西,这种方法变得困难。值得注意的是:
在我们当前的原型中,我们通过为每个功能配置套件和参数构造函数来解决这个问题。看起来像这样:
// Library code.
abstract class LibFeatureATest(impl: LibInterface, prop: String, paramA: Boolean)
abstract class LibFeatureBTest(impl: LibInterface, prop: String)
abstract class LibFeatureABTest(impl: LibInterface, prop: String, paramA: Boolean)
// Client code:
class FeatureATest(new MyInterfaceImpl, "my_prop", true)
class FeatureATest(new MyInterfaceImpl, "my_prop", false)
class FeatureBTest(new MyInterfaceImpl, "my_prop")
class FeatureABTest(new MyInterfaceImpl, "my_prop", true)
class FeatureABTest(new MyInterfaceImpl, "my_prop", false)
这种方法存在两个主要问题:
理想情况下,我们希望在客户端中拥有类似的内容:
class MyTest extends TestSuite(new MyInterfaceImpl,
prop = "my_prop",
supportsA = true,
supportsB = true)
确切的调用语法/类型是次要的(抽象方法,参数,注释)。但请注意这些额外要求:
Enclosing
)可能无效。我们如何在sbt上的Scala中的JUnit4中执行此操作?
答案 0 :(得分:0)
您可以分别实现提供参数化和配置的JUnit规则。
可以从文件中读取配置(即客户端提供的属性),以便客户端可以单独提供,而无需更改测试本身;然后,规则将根据配置启用或禁用测试用例。
“参数化”的含义尚不清楚,但我确信你可以使用规则。它们基本上是“围绕” - 测试用例的方面。
编辑:
所以这就是我想象你的界面:
import json
file_name = "storing and reading JSON\user_number.json"
with open(file_name) as j_obj:
num = json.load(j_obj)
print("I know your favorite number, it's: " + str(num))
完整的单元测试就是
interface ToTest {
int getFeature1Value(); // let's say this needs to return 1 for compliance, if feature1 is supported
int getFeature2Value(); // so this is a feature2 method, and needs to return 2
}
但IIUC您希望客户端能够指定支持哪些功能,如果不支持,则禁用该测试用例。这就是我使用FeatureSupport注释注释测试用例的原因,这是一个
public class ComplianceTest {
// the rule being applied, see below
@Rule DisablingRule rule = new DisablingRule("feature_config.prop");
@Autowired // so this would need to run in a DI environment
ToTest sut;
@FeatureSupport(condition = Features.Feature1) // see below
@Test public void testFeature1() {
assertEquals(1, sut.getFeature1Value());
}
@FeatureSupport(condition = Features.Feature2)
@Test public void testFeature2() {
assertEquals(2, sut.getFeature2Value());
}
}
带
@interface FeatureSupport {
Features getCondition();
}
这就是编写规则的设置,类似于
enum Features {
Feature1, Feature2
}
答案 1 :(得分:0)
我错过了你的“理想情况下我们希望在客户端拥有这样的东西”,这使事情变得更容易。
public interface MyTest<T> extends Test {
public void setSut(T toTest);
public void setProperties(Properties props);
}
public enum Features {
Feature1(Feature1UnitTest::new),
Feature2(Feature2UnitTest::new);
private Supplier<? extends Test> createTest;
private Features(Supplier<? extends Test> sup) {
createTest = sup;
}
}
public class MyTestSuite<T> extends TestSuite {
public MyTestSuite(T toTest, Properties testProperties, Features... supported) {
for (Features f : supported) {
MyTest<T> test = (MyTest<T>) f.createTest();
test.setSut(toTest);
test.setProperties(testProperties);
addTest(test);
}
}
}