参考内容:
单元测试: 隔离程序部件验证单个部件的正确性(以程序模块为单位比较输出结果和预期结果是否一致)
过程式编程中一个单元:单个程序、函数以及过程。
面向对象编程中一个单元:父类、子类、抽象类中的方法。为了保证程序的正确性每次代码的修改都要执行对应的单元测试以发现程序中错误并进行定位和修复。
JUnit provide overloaded assertion methods for all primitive types and Objects and arrays
The parameter order is eexpected value followed by actual value.
Optinally the first parameter can be a String message that is output on failure.
*AssertTests.class
public class AssertTests {
@Test
public void testAssertArrayEquals(){
byte[] expected = "trial".getBytes();
byte[] actual = "trail".getBytes();
// 测试两个数组包含的内容是否相同(第一个参数是在不同的情况下即failure时输出的内容)
assertArrayEquals("failure - byte arrays not same", expected, actual);
}
@Test
public void testAssertEquals(){
// 测试两个字符串是否相同
assertEquals("failure - strings are not equal", "Java", "Python");
}
@Test
public void testAssertFalse(){
// 测试是否为false, 如果是false测试成功否则输出测试失败信息
// assertFalse("failure - should be false", true); java.lang.AssertionError: failure - should be false
assertFalse("failure - shoudl be false", false);
// assertTrue("error: msg", boolean val); 测试是否为true
}
@Test
public void testAssertNotNull(){
assertNotNull("should not be null", null); // java.lang.AssertionError: should not be null
// assertNotNull("should not be null", new Object());
}
@Test
public void testAssertNotSame(){
// assertNotSame("should be the same object", new Object(), new Object());
}
@Test
public void testAssertSame(){
Integer aNumber = Integer.valueOf(768);
assertSame("should be same", aNumber, 123); // java.lang.AssertionError: should be same expected same:<768> was not:<123>
}
@Test
public void testAssertThatBothContainsString(){
// JUnit Matchers assertThat
assertThat("username: wangzz", both(containsString("username")).and(containsString("wangzz")));
}
@Test
public void testAssertThatHasItems(){
assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
}
@Test
public void testAssertThatEveryItemContainsString(){
assertThat(Arrays.asList(new String[]{"fun", "ban", "net"}), everyItem(containsString("n")));
}
// Core Hamcrest Matchers with assertThat
@Test
public void testAssertThatHamcrestCoreMatchers(){
assertThat("good", allOf(equalTo("good"), startsWith("good")));
}
When a class is annotated with
@RunWith
or extends a class annotated with@RunWith
, JUnit will invoke the class it references(调用它所引用的类) to run the tests in that class instead of the runner built into JUnit.
* JavaDoc for @RunWith http://junit.org/javadoc/latest/org/junit/runner/RunWith.html
* The default runner is BlockJUnit4ClassRunner which supersedes the older JUnit4ClassRunner.
* Annotating a class with@RunWith(JUnit4.class)
will always invoke the deault JUnit 4 runner in the current version of JUnit.
测试套件用于批量运行测试类
Suite
is a standard runner that allows you to mannually build a suite containing tests from many classses.<a href=‘http:/junit.org/javadoc/latest/org/junit/runners/Suite.html
随着项目进度的开展,单元测试类会越来越多,为了实现自动化批量处理,JUnit提供了一种批量运行测试类的方法,叫做测试套件。
每次需要验证系统功能正确性的时候,只执行一个或几个测试套件便可以了。
遵循的规则:
Using
Suite
as a runner allows you to manually build a suite containing tests from many classes.
To use it, annotate a class with@RunWith(Suite.class)
and@SuiteClasses(TestClass1.class, ...)
. When you run this class, it will run all the tests in all the suite classes.
Example
Note the
@RunWith
annotation, with specifies that the JUnit4 test runner to use isorg.junit.runners.Suite
for running this particular test class. This works in conjunction with the@Suite.SuiteClasses
annotation, which tells the Suite runner which test classes to include in this suite and in which order.(它告诉套件运行程序在这个套件中包含哪些测试类以及以什么顺序包含。)
* TestFeatureLogin.class
public class TestFeatureLogin{
public TestFeatureLogin(){}
@Test
public void testAssertThatBothContainsUsername(){
assertThat("username: wangzz",
both(containsString("username"))
.and(containsString("wangzz")));
}
}
*TestFeatureLogout.class
public class TestFeatureLogout{
public TestFeatureLogout(){}
@Test
public void testAssertEquals(){
assertEquals("退出应用失败!","0","0");
}
}
*TestFeatureNavigate.class
public class TestFeatureNavigate{
public TestFeatureNavigate(){}
@Test
public void testAssertTrue(){
assertTrue("导航失败!",true);
}
}
*TestFeatureUpdate.class
public class TestFeatureUpdate{
public TestFeatureUpdate(){}
@Test
public void testFeatureUpdate(){
assertNotNull("数据获取失败", new Object());
}
}
*TestFeatureSuite.class
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
TestFeatureLogin.class,
TestFeatureLogout.class,
TestFeatureNavigate.class,
TestFeatureUpdate.class
})
public class TestFeatureSuite {
}
*TestRunner.class
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(TestFeatureSuite.class);
for(Failure failure : result.getFailures()){
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
===》输出
true
Parameterized
is a standard runner that implements parameterized tests.When running a parameterized test class, instances are created for the cross-product of the test methods and the test data elements.
Example
*Fibonacci.class
public class Fibonacci {
public static int compute(int n){
if(n <= 1){
return n;
}
return n * compute(n - 1);
}
}
*FibonacciTest.class
@RunWith(Parameterized.class)
public class FibonacciTest {
@Parameterized.Parameters
public static Collection<Object[]> data(){
return Arrays.asList(new Object[][]{
{0, 0}, {1, 1}, {2, 1},
{3, 2}, {4, 3}, {5, 5},
{6, 8}
});
}
private int fInput;
private int fExpected;
public FibonacciTest(int input, int expected){
this.fInput = input;
this.fExpected = expected;
}
@Test
public void testAssertEquals(){
assertEquals(fExpected, Fibonacci.compute(fInput));
}
}
===》输出
java.lang.AssertionError:
Expected :1
Actual :2
<Click to see difference>
java.lang.AssertionError:
Expected :2
Actual :6
<Click to see difference>
java.lang.AssertionError:
Expected :3
Actual :24
<Click to see difference>
java.lang.AssertionError:
Expected :5
Actual :120
<Click to see difference>
java.lang.AssertionError:
Expected :8
Actual :720
<Click to see difference>
It is also possible to inject data values directly into fields without needing a constructor using the @Parameter annotation.
If your test needs a single parameter only, you do not have to wrap it with an array. Instead you can provide an Iterable or an array of objects.
@Parameters
public static Iterable<? extends Object> data(){
return Arrays.asList("first test", "second test");
}
or
@Parameters
public static Object[] data(){
return new Object[] {"first test", "second test"};
}
In order to easily identify the individual test cases in a Parameterized test, you may provide a name using the @Parameters annotation. This name is allowed to contain placeholders that are replaced at runtime: (此名称允许包含在运行时被替换的占位符)
{index}
: the current parameter index{0}, {1}, ...
: the first, second, and so on, parameter value. NOTE: single quotes `
should be escaped as two single quotes‘‘
.Example
@RunWith(Parameterized.class)
public class FibonacciTest {
@Parameterized.Parameters(name = "{index}: fib({0})={1}")
public static Iterable<Object[]> data(){
return Arrays.asList(new Object[][]{
{0, 0}, {1, 1}, {2, 1}, {3, 2}, {4, 3}, {5, 5}, {6, 8}
});
}
private int input;
private int expected;
public FibonacciTest(int input, int expected){
this.input = input;
this.expected = expected;
}
@Test
public void test(){
assertEquals(expected, Fibonacci.compute(input));
}
}
原文:https://www.cnblogs.com/openmind-ink/p/14352848.html