单元测试一——Junit3

本文介绍了如何使用Java创建测试用例,通过接口Person定义公共行为,抽象类BasePerson实现基础属性和方法,具体展示了Teacher类的继承和测试。使用JUnit框架编写了TeacherTest类,包括setUp(), tearDown(), 和多个测试方法,如eat(), sport(), work()的测试。最后讨论了测试套件和JUnit Core的使用,便于批量执行和组织测试代码。

测试用例

测试用例是可以确保另一段代码(方法)按预期工作一部分代码,而一个良好的单元测试用例的特点是:已知输入和预期输出,每一项需求至少需要两个单元测试用例:一个正检验,一个负检验。如果一个需求有子需求,每一个子需求必须至少有正检验和负检验两个测试用例。

业务对象

前面的过程描述了使用注解的方式,接下来我们尝试下通过继承类来构建测试用例的方式,另外这里针对待测试类做了些简单的抽象,考虑到无论是教职工还是学生都具有姓名和年龄这两个属性,并且都具备用餐与运动两种行为,故此创建了接口及抽象类供继承使用,以及消除冗余代码

Step 1: 创建接口 Person.java

public interface Person {
    /**
     * 用餐
     * @return
     */
    public abstract String eat();

    /**
     * 运动
     * @return
     */
    public abstract String sport();
}

Step 2: 创建抽象类 BasePerson.java

public abstract class BasePerson implements Person {
    private String name;
    private int weight;

    public BasePerson() {
    }

    public BasePerson(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }

    @Override
    public void eat() {
        System.out.println("民以食为天!");
        setWeight(weight + 1);
        System.out.println("体重增加了=====>" + weight);
    }


    @Override
    public void sport() {
        System.out.println("生命在于运动!");
        setWeight(weight - 1);
        System.out.println("体重减轻了=====>" + weight);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "BasePerson{" +
                "name='" + name + '\'' +
                ", weight=" + weight +
                '}';
    }
}

Step 3: 创建待测试类 Teacher.java

public class Teacher extends BasePerson {

    public Teacher() {
    }

    public Teacher(String name, int weight) {
        super(name, weight);
    }

    public void work() {
        System.out.println("春风化雨,桃李天下!");
    }
}

测试工具
------------	
	
junit.framework.TestCase
	setUp()
	tearDown()
	assertTrue(Boolean bool)
	
1	int countTestCases()
为被run(TestResult result) 执行的测试案例计数
2	TestResult createResult()
创建一个默认的 TestResult 对象
3	String getName()
获取 TestCase 的名称
4	TestResult run()
一个运行这个测试的方便的方法,收集由TestResult 对象产生的结果
5	void run(TestResult result)
在 TestResult 中运行测试案例并收集结果
6	void setName(String name)
设置 TestCase 的名称
7	void setUp()
创建固定装置,例如,打开一个网络连接
8	void tearDown()
拆除固定装置,例如,关闭一个网络连接
9	String toString()
返回测试案例的一个字符串表示

Step 4: 创建测试类 TeacherTest.java

public class TeacherTest extends TestCase {
    private Teacher teacher;

    protected void setUp(){
        System.out.println("setUp...");
        teacher = new Teacher("Joyce", 67);
    }

    public void testEat(){
        teacher.eat();
        assertEquals(68,teacher.getWeight() );
    }
    public void testSport(){
        teacher.sport();
        assertTrue(66 == teacher.getWeight());
    }

    public void testWork(){
        teacher.work();
    }

    public void tearDown(){
        System.out.println("tearDown...");
    }
}
测试运行器
public class RunnerTest {
    @Test
    public void testJUnitCore() {
        Result result = JUnitCore.runClasses(TeacherTest.class);
        for (Failure failure :
                result.getFailures()) {
            System.out.println(failure.toString());
        }
        System.out.println(result.wasSuccessful());
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qywh8n46-1603536448641)(D:\blog\0-图说百态\assets\01-JUnit单元测试\image-20200904004711214.png)]

测试用例是使用 JUnitCore 类来执行的。JUnitCore 是运行测试的外观类。要从命令行运行测试,可以运行java org.junit.runner.JUnitCore。对于只有一次的测试运行,可以使用静态方法 runClasses(Class[])

测试用例是使用 JUnitCore 类来执行的。JUnitCore 是运行测试的外观类。它支持运行 JUnit 4 测试, JUnit 3.8.x 测试,或者他们的混合。 要从命令行运行测试,可以运行 java org.junit.runner.JUnitCore 。对于只有一次的测试运行,可以使用静态方法 runClasses(Class[])。
org.junit.runner.JUnitCore
	runClasses(Class clazz);
org.junit.runner.Result
	getFailures()
	wasSuccessful()
org.junit.runner.notification.Failure
	toString()
TestResult 类收集所有执行测试案例的结果。它是收集参数层面的一个实例。这个实验框架区分失败和错误。失败是可以预料的并且可以通过假设来检查。错误是不可预料的问题就像 ArrayIndexOutOfBoundsException。TestResult 类的一些重要方法列式如下

1	void addError(Test test, Throwable t)
在错误列表中加入一个错误
2	void addFailure(Test test, AssertionFailedError t)
在失败列表中加入一个失败
3	void endTest(Test test)
显示测试被编译的这个结果
4	int errorCount()
获取被检测出错误的数量
5	Enumeration errors()
返回错误的详细信息
6	int failureCount()
获取被检测出的失败的数量
7	void run(TestCase test) 运行 TestCase
8	int int runCount()
获得运行测试的数量
9	void startTest(Test test)
声明一个测试即将开始
10	void stop()
标明测试必须停止

测试套件
@RunWith(Suite.class)
@Suite.SuiteClasses({StudentTest.class, TeacherTest.class})
public class SuiteTest {
}

随着项目进度的开展,单元测试类会越来越多,可是直到现在我们还只会一个一个的单独运行测试类,这在实际项目实践中肯定是不可行的。为了解决这个问题,JUnit 提供了一种批量运行测试类的方法,叫做测试套件。

测试套件意味着捆绑几个单元测试用例并且一起执行他们。在 JUnit 中,@RunWith@Suite注释用来运行套件测试。

每次需要验证系统功能正确性时,只执行一个或几个测试套件便可以了。测试套件的写法非常简单,我们需要遵循以下规则:

创建一个空类作为测试套件的入口。
使用注解 org.junit.runner.RunWith 和 org.junit.runners.Suite.SuiteClasses 修饰这个空类。
将 org.junit.runners.Suite 作为参数传入注解 RunWith,以提示 JUnit 为此类使用套件运行器执行。
将需要放入此测试套件的测试类组成数组作为注解 SuiteClasses 的参数。
保证这个空类使用 public 修饰,而且存在公开的不带有任何参数的构造函数。
测试套件中不仅可以包含基本的测试类,而且可以包含其它的测试套件,这样可以很方便的分层管理不同模块的单元测试代码。

注意:一定要保证测试套件之间没有循环包含关系,否则无尽的循环就会出现在我们的面前。

org.junit.runner.RunWith;
org.junit.runner.Suite;
 
@RunWith(Suite.class)
@Suite.SuiteClasses({
	Class clazz1,Class clazz2...
})
public class JunitTestSuite{}
TestSuite 类是测试的组成部分。它运行了很多的测试案例。TestSuite 类的一些重要方法列式如下:

1	void addTest(Test test) 
在套中加入测试。
2	void addTestSuite(Class<? extends TestCase> testClass)
将已经给定的类中的测试加到套中。
3	int countTestCases()
对这个测试即将运行的测试案例进行计数。
4	String getName()
返回套的名称。
5	void run(TestResult result)
在 TestResult 中运行测试并收集结果。
6	void setName(String name)
设置套的名称。
7	Test testAt(int index)
在给定的目录中返回测试。
8	int testCount()
返回套中测试的数量。
9	static Test warning(String message)
返回会失败的测试并且记录警告信息。

Student

Teacher

StudentTest

TeacherTest

TestRunner

SuiteTest

SuiteGroupTest

JUnit 测试框架具有以下重要特性:

测试工具
测试套件
测试运行器
测试分类


测试工具是一整套固定的工具用于基线测试。测试工具的目的是为了确保测试能够在共享且固定的环境中运行,因此保证测试结果的可重复性。它包括:

在所有测试调用指令发起前的 setUp() 方法。
在测试方法运行后的 tearDown() 方法。


测试套件
测试套件意味捆绑几个测试案例并且同时运行。在 JUnit 中,@RunWith 和 @Suite 都被用作运行测试套件。以下为使用 TestJunit1 和 TestJunit2 的测试分类:


测试运行器
测试运行器 用于执行测试案例。以下为假定测试分类成立的情况下的例子:
org.junit.runner.JUnitCore
org.junit.runner.Result
org.junit.runner.notificaition.Failure

JUnit 测试分类
测试分类是在编写和测试 JUnit 的重要分类。几种重要的分类如下:

包含一套断言方法的测试断言
包含规定运行多重测试工具的测试用例
包含收集执行测试用例结果的方法的测试结果

更多特性

忽略测试

有时可能会发生我们的代码还没有准备好的情况,这时测试用例去测试这个方法或代码的时候会造成失败。@Ignore 注释会在这种情况时帮助我们。

一个含有 @Ignore 注释的测试方法将不会被执行。
如果一个测试类有 @Ignore 注释,则它的测试方法将不会执行。
在类级别上使用 @Ignore 来忽略所有的测试用例

JUnit 参数化测试

Junit 4 引入了一个新的功能参数化测试。参数化测试允许开发人员使用不同的值反复运行同一个测试。你将遵循 5 个步骤来创建参数化测试。

  • @RunWith(Parameterized.class) 来注释 test 类。
  • 创建一个由 @Parameters注释的公共的静态方法,它返回一个对象的集合(数组)来作为测试数据集合。
  • 创建一个公共的构造函数,它接受和一行测试数据相等同的东西。
  • 为每一列测试数据创建一个实例变量。
  • 用实例变量作为测试数据的来源来创建你的测试用例。

一旦每一行数据出现测试用例将被调用。

建议

①测试方法上必须使用@Test进行修饰
②测试方法必须使用public void 进行修饰,不能带任何的参数

③新建一个源代码目录来存放我们的测试代码,即将测试代码和项目业务代码分开

④测试类所在的包名应该和被测试类所在的包名保持一致

⑤测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖

⑥测试类使用Test作为类名的后缀(不是必须)

⑦测试方法使用test作为方法名的前缀(不是必须)

参考资料



https://blog.csdn.net/u012085824/article/details/80254434

测试

5.JUnit测试框架目前大体分为两种(JUnit 3.8 和 JUnit 4.x)

 

———————————— JUnit 3.8 ———————————————

涉及到的包一般是 import junit.framework.*

6.在 JUnit 3.8 中,测试类要继承TestCast类,而TestCast类又继承于Assert类,测试方法需满足如下原则:

1)修饰符设为 public

2)返回类型 void

3)没有方法参数

4)方法名称必须以test开头

 

7.不能依赖于测试方法的执行顺序

 

8.setUp方法和testDown方法都是TestCase类的方法

1)setUp方法是在执行每个测试方法之前执行的

2)testDown方法是在执行每个测试方法之后执行的

 

———————————— JUnit 4 ———————————————

涉及到的包是 import org.junit.*

9)在junit 4 当中测试类无需继承于 TestCase类,测试方法的名字也无需以test开头,主要以注解的方式来定义,只要在测试方法加上@Test就可以进行测试,但有些原则还是要以junit3 的风格来设计,比如测试方法以test开头,习惯问题吧,

10)

@Test :定义一个测试方法的标志
@Test(timeout=1000) :设置超时时间,如果测试时间超过了你定义的timeout,测试失败
@Test(expected) : 申明出会发生的异常,比如 @Test(expected = Exception.class)
@Before : 跟junit 3.8 上的setUp() 方法同样的效果,方法名最好和setUp()一样,但不强求,在每一个测试方法之前被执行
@After : 跟junit 3.8 上的tearDown() 方法同样的效果,方法名最好和tearDown()一样,但不强求,在每一个测试方法之后被执行
@BeforeClass : 被该注解申明的方法,功能是:在所有的测试方法之前执行,只执行一次
@AfterClass : 被该注解申明的方法,功能是:在所有的测试方法之后执行,只执行一次
@Ignore :让 测试方法 或 测试类 不被执行,让其失去测试的功能
内容概要:本文提出了种基于改进扩散模型的高海拔地区新能源高波动出力场景生成方法,提供了完整的Python代码实现。该方法针对高海拔地区风能、光伏等新能源出力波动剧烈、不确定性高的特点,通过优化扩散模型的结构训练策略,有效捕捉历史数据的概率分布特征时序相关性,从而生成高质量、多样化的出力场景。文中详细阐述了模型的数学推导、网络架构设计、损失函数优化及采样算法改进,通过实验证明其在拟合精度、场景多样性稳定性方面优于传统生成模型,为电力系统在高比例新能源接入下的规划、调度风险评估提供了可靠的场景输入支持。; 适合人群:具备定Python编程能力和机器学习基础,从事新能源发电预测、电力系统分析、智能优化、场景生成等方向研究的科研人员、高校研究生及工程技术人员。; 使用场景及目标:①用于高海拔地区风电、光伏出力的不确定性建模多场景生成;②支撑含高渗透率新能源的电力系统随机优化调度、鲁棒决策风险评估;③为相关学术研究、论文复现算法改进提供可运行的技术方案代码基础; 阅读建议:建议读者结合所提供的完整资源(代码、数据集、说明文档)进行实践操作,重点关注扩散模型的前向加噪反向去噪过程的设计细节,以及如何将其适配于新能源时序数据的生成任务,通过参数调优对比实验深入理解模型的生成机制性能边界。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值