Java 作为库的一部分提供测试
假设一个接口如下:Java 作为库的一部分提供测试,java,unit-testing,testing,junit,Java,Unit Testing,Testing,Junit,假设一个接口如下: public interface Fooer { void foo(); boolean isFooed(); } 这是我正在编写的Java库的一部分。这个库的用户应该实现这个接口并将对象传递到我的库中 我想为用户提供一种方法来测试他们的实现,以保存我的库代码假定的不变量 按照上述示例: Fooer f = getUsersFooer(); f.foo(); // f.isFooed() MUST return true now 作为库的一部分提供此类测试是否可行
public interface Fooer {
void foo();
boolean isFooed();
}
这是我正在编写的Java库的一部分。这个库的用户应该实现这个接口并将对象传递到我的库中
我想为用户提供一种方法来测试他们的实现,以保存我的库代码假定的不变量
按照上述示例:
Fooer f = getUsersFooer();
f.foo();
// f.isFooed() MUST return true now
作为库的一部分提供此类测试是否可行,如果可行,甚至可以接受
(我不知道这些是单元测试还是集成测试……它们使用getter方法或非常原始的非变异方法测试单个方法所做的修改)
当然,我可以写像这样的类
public class TestFooer {
public static boolean test(Fooer f) {
// ...
}
}
但是,是否有一种“标准方法”,使用常用的测试框架(JUnit,…)这是一种常用的模式,用于检查某些规范的实现的符合性。这称为TCK。我没有看过很多TCK的代码,但我看到它们经常使用 JUnit5.8.0-M1最近增加了一个功能,允许定义可用于此功能的测试套件 您的TCK对您的API和
org.junit.jupiter:junit-jupiter
(至少5.8.0-M1
)以及org.junit.platform:junit平台套件
(至少1.8.0-M1
)具有非测试依赖性。测试不在src/test/java
中,而是src/main/java
中。然后向TCK添加一个套件类,如:
package org.example;
导入org.junit.platform.suite.api.SelectPackages;
导入org.junit.platform.suite.api.suite;
@套房
@选择软件包(“org.example”)
公共抽象类TestCompatibilityKitSuite{}
请注意,这个类不必是抽象的,我只是认为它使预期的用法更加清楚
然后,实现依赖于api
,依赖于tck
。要运行测试,请添加一个类,如:
封装测试;
导入org.example.testcompatibilitykisuite;
类TckTest扩展了TestCompatibilityKitSuite{}
TCK必须加载实现。这样做的一个好方法是使用
java.util.ServiceLoader
。查看完整示例。这是一种常用模式,用于检查某些规范的实现是否符合要求。这称为TCK。我没有看过很多TCK的代码,但我看到它们经常使用
JUnit5.8.0-M1最近增加了一个功能,允许定义可用于此功能的测试套件
您的TCK对您的API和org.junit.jupiter:junit-jupiter
(至少5.8.0-M1
)以及org.junit.platform:junit平台套件
(至少1.8.0-M1
)具有非测试依赖性。测试不在src/test/java
中,而是src/main/java
中。然后向TCK添加一个套件类,如:
package org.example;
导入org.junit.platform.suite.api.SelectPackages;
导入org.junit.platform.suite.api.suite;
@套房
@选择软件包(“org.example”)
公共抽象类TestCompatibilityKitSuite{}
请注意,这个类不必是抽象的,我只是认为它使预期的用法更加清楚
然后,实现依赖于api
,依赖于tck
。要运行测试,请添加一个类,如:
封装测试;
导入org.example.testcompatibilitykisuite;
类TckTest扩展了TestCompatibilityKitSuite{}
TCK必须加载实现。这样做的一个好方法是使用
java.util.ServiceLoader
。查看完整的示例。我不知道是否有标准方法,但是fwiw,而不是静态方法,我将使用单个抽象方法createFoo()创建一个抽象类,然后是具体的测试方法。或者某种DI——DI框架和测试框架之间可能存在集成。我认为没有标准的方法来实现这一点,但是静态方法是一种很好的方法。您不应该在库中使用任何JUnit代码,并且通过简单地抛出AssertionError来进行断言。这使您的测试可用于TestNG和JUnit。这些测试是集成测试:它们测试关于其他组件的假设是否成立。相反,在单元测试中,当您创建double(mock、stub)时,您可以根据您对其他组件的假设来实现它们。也就是说,单元测试不适合识别对其他组件的误解。我不知道是否有标准方法,但fwiw,而不是静态方法,我将使用单个抽象方法createFoo()创建一个抽象类,然后使用具体的测试方法。或者某种DI——DI框架和测试框架之间可能存在集成。我认为没有标准的方法来实现这一点,但是静态方法是一种很好的方法。您不应该在库中使用任何JUnit代码,并且通过简单地抛出AssertionError来进行断言。这使您的测试可用于TestNG和JUnit。这些测试是集成测试:它们测试关于其他组件的假设是否成立。相反,在单元测试中,当您创建double(mock、stub)时,您可以根据您对其他组件的假设来实现它们。也就是说,单元测试不适合识别对其他组件的误解。