本帖最后由 奇犽 于 2019-2-13 15:15 编辑
1、为什么需要测试?所以如果你遇到如上问题,就需要写测试。写测试可能是为了自己(1、2);也可能是为了帮助别人(3)。
2、如何进行测试?很多朋友不知道如何进行测试,其实测试很简单,别把它想复杂了,按照自己的想法测试每个功能点是否正确即可。
2.1、测试流程集成·测试流程 单元·测试流程 可以看出,单元测试与集成测试唯一不同点是一个调用依赖系统而一个不调用;因为单元测试是最小粒度的测试,如在Java中是测试一个类,不会测试依赖系统;而集成测试是会测试依赖系统的。 测试的步骤: 环境:也叫做夹具(fixture)或者固件,表示调用被测系统时需要准备/清理的数据等等; 被测系统:在Java中就是要测试的类,如UserService; 依赖系统:测试被测系统时,其依赖的部分,如UserDao; 测试用例:包含测试方法的类,里边有很多测试方法来测试被测系统。 接下来仔细看看各部分都做了哪些工作。
2.2、环境环境,也叫做夹具(fixture),表示调用被测系统时需要准备/清理的数据等等;保证测试时环境是干净的,如不被之前的数据库数据影响;保证每次测试都是在干净/新鲜的环境中执行的。所谓干净的环境表示如当前测试不被之前测试插入/删除/修改的数据造成影响。在junit中可以使用: @Before(setUp) 安装夹具或准备环境:在测试用例的每个测试方法之前执行;比如创建新鲜的被测系统,单元测试时安装Mock的依赖系统; @After(tearDown)卸载夹具或清理环境:在测试用例的每个测试方法之后执行;比如数据库测试时回滚事务,删除数据;关闭文件; @BeforeClass:在整个测试用例之前执行; @AfterClass:在整个测试用例之后执行;
使用如上方法,而不是直接在测试方法中安装/卸载;是因为不管有没有异常,@After/@AfterClass都会执行,这样防止出现异常可能造成环境是不新鲜的问题。 如果大家使用spring test来测试数据库相关的系统,可以考虑使用@TransactionConfiguration来支持默认事务回滚,这样不会对现有系统造成影响。 测试时一定要保证环境是干净/新鲜的,才能保证每次测试的结果是一样的。
2.3、被测系统与依赖系统被测系统:在Java中就是被测试的Java类。 依赖系统:就是被测试Java类依赖的其他类。 如果是单元测试,一般情况下,会对依赖系统进行模拟(Mock),即给它一个假的实现;典型的如测试服务层时注入一个Mock的DAO层,这样的好处: 如果是集成测试时,直接注入真实的依赖系统即可,好处: 完成联调; 发现自己的问题; 还可能发现自己使用上问题及使用的API的问题;
单元测试虽然好,但是是隔离测试,即不会调用被测系统来完成测试,因为不是真实的联调,所以很可能会潜在有一些问题,因此还是需要集成测试。(所以不是很刻意分单元或集成测试,且有些系统可能只有集成测试) 但是集成测试速度是比较慢的,一般提交给CI执行,不影响当前开发进度。
2.4、验证验证的目的:是保证实际结果和我们预期的结果是否一致,说白了就是是否是我们想的那样。 一般使用断言来验证,如: Assert.assertEquals(expectedResult, actualResult); //验证预期结果和实际结果是否相等 验证主要有两种:
结果验证:即验证被测系统返回的结果是否正确,如: - @Test
- public void testCount() {
- String ql = "select count(o) from User o";
- long expectedCount = repositoryHelper.count(ql) + 1;
- User user = createUser();
- repositoryHelper.getEntityManager().persist(user);
- long acutalCount = repositoryHelper.count(ql);
- Assert.assertEquals(expectedCount, acutalCount);
- }
复制代码验证返回的数据总数 = 插入之前的总数 + 1; 即结果验证。此处我们使用了一种叫做相对(delta)测试;即不关心数据库里到底多少条,只关心实际的和预期的差。 行为验证:即验证被测系统是否调用了依赖系统的某个API ,这个只有当我们使用Mock时测试时比较简单,如当用户注册时: 1、加积分 2、发系统消息 3、…… 此时我们并不能通过结果验证是否调用了这些方法;那么我们可以使用Mock技术来完成验证是否调用了这些API,比如使用jmock测试框架就支持行为验证。集成测试是很难进行行为验证的,如果测试需要预留间谍接口。
3、测试有哪些好处? 我们写代码的目的是正确的完成某个功能,如何保证正确呢?测试!所以在不使用如单元测试技术时,我们也是需要测试,但是这个测试是我们人工验证的。缺点很明显: 为了解决这个问题,我们使用如单元测试技术来解决这个问题: 即测试的好处,从如上已经提炼出来了: 缩短发现问题到解决问题的时间; 重复使用测试,保证修改后的代码还是正确的; 如果做开源项目,可以提供给使用人员参考如何使用; 因为单元测试都非常快,所以提升了开发速度;
4、一切都需要测试吗?肯定不是,一切都是相对的;哪些不需要测试呢: 哪些需要测试呢: 复杂的业务逻辑/系统核心功能,最典型的如订单系统:一定要有足够的单元测试保证,这是一个电商系统的核心;还有如用户系统、积分系统等等; 框架级别/工具级别/通用级别的代码需要测试,即提供给第三方使用的代码,因为这些代码可能被很多系统依赖,应该保证其正确性;而且还要保证以后版本升级的向下兼容; 你认为需要测试的,比如你没有把握的东西,还是写点测试来缩短如开发web项目的重启系统的时间吧;
测试不是不耗时间的,没意义的测试就是浪费时间,最典型是一些书上的对一个增删改查进行测试,实际项目没有任何意义。所以你应该只对自己很难驾驭的觉得有必要的代码进行测试。不要成为一个测试狂,什么都测试。
|