当前位置: 首页 > news >正文

网站开发人员招聘紧急通知界面访问升级中狼人

网站开发人员招聘,紧急通知界面访问升级中狼人,建筑行业大数据综合查询平台官网,中山网站建设公司排名什么是单元测试#xff1f; Wikipedia 对单元测试的定义#xff1a; 在计算机编程中#xff0c;单元测试#xff08;Unit Testing#xff09;又称为模块测试#xff0c;是针对程序模块#xff08;软件设计的最小单位#xff09;来进行正确性检验的测试工作。 在实际…什么是单元测试 Wikipedia 对单元测试的定义 在计算机编程中单元测试Unit Testing又称为模块测试是针对程序模块软件设计的最小单位来进行正确性检验的测试工作。 在实际测试中一个单元可以小到一个方法也可以大到包含多个类。从定义上讲单元测试和集成测试是有严格的区分的但是在实际开发中它们可能并没有那么严格的界限。如果专门追求单元测试必须测试最小的单元反而容易造成多余的测试并且不易维护。换句更严谨一点的说法我们要考虑测试的场景再去选择不同粒度的测试。 单元测试和集成测试即可以手工执行也可以是程序自动执行。但现在一般提到单元测试都是指自动执行的测试。所以我们下面提到的单元测试没有特别注明都是泛指自动执行的单元测试或集成测试。 单元测试入门 下面我们先看两个案例感受一下单元测试到底是什么样子的。 例子 1生命游戏单元测试 我们先看一个很简单的例子实现一个康威生命游戏。如果不了解康威生命游戏的话可以看 Wikipedia 的介绍。假设我们实现时定义这样的接口 public interface Game { void init(int[][] shape) ; // 初始化游戏 board void tick(); // 行进到在一个回合 int[][] get(); // 获取当前游戏 board } 生命游戏有好几条规则为了测试我们的实现是否正确我们可以针对生命游戏的每个规则写一个单元测试。下面测试的是复活的规则。 Test public void testRelive() { int[][] shape {{0, 0, 1}, {0, 0, 0}, {1, 0, 1}}; Game g new GameImplSample(shape); g.tick(); // 自己死亡周围3个存活状态复活 assertEquals(1, g.get()[1][1]); } 例子 2订单退款集成测试 我们在看一个稍微复杂一些的例子测试的是订单退款的过程。 Test public void test300_doRefundItem() { // 创建订单、支付然后退款 Order order createOrder(OrderSource.XR_DOCTOR); order fullPay(order, PayType.WECHAT_JS); OrderItem item _doItemRefund(order, 1, false); // 检查退款中状态 OrderWhole orderWholeRefunding findOrderWhole(order.getOrderNo()); isTrue(orderWholeRefunding.getRefundStatus().equals( OrderRefundStatus.PARTIAL_REFUNDING)); isTrue(orderWholeRefunding.getRefunds().get(0).getStatus().equals( RefundStatus.REFUNDING)); isTrue(orderWholeRefunding.getRefunds().get(0).getItemId().get().equals( item.getId())); // 构建退款的回调信息 List payments findPayments(order.getId()); List refunds findRefunds(order.getId()); wxRefundNotify(payments.get(0), refunds.get(0), WxRefundStatus.SUCCESS); // 检查退款后状态 OrderWhole orderWholeFinish assertRefund(order, FULL_PAID, PARTIAL_REFUND_OK, RefundStatus.SUCCESS, RefundMode.ITEM, false); isTrue(orderWholeFinish.getRefundFee() item.getPaidPrice()); isTrue(orderWholeFinish.getIncomes().stream() .filter(i - i.getAmount() 0).count() 1); } 单元测试执行 单元测试有很多种执行方式 在 IDE 中执行 通过 mvn 或者 gradle 运行 在 CI 中执行 不论什么方式单元测试都应该很容易就能运行并给出一个测试结果。当然单元测试运行速度得快一般是在秒级的太慢的话就不能及时获得反馈了。 为什么要写单元测试 单元测试的好处 确保代码满足需求或者设计规格。 使用单元测试来测试代码可以通过构造数据和前置条件确保测试覆盖到需要测试的逻辑。而手工测试或 UI 测试则无法做到并且往往更复杂。 快速定位并解决问题。 单元测试因为测试范围比较小可以比较容易的定位到问题而手工测试常常需要耗费不少时间去定位问题。 确保代码永远满足需求规格。 一旦需要对实现进行修改单元测试可以确保代码的正确性极大的降低各种修改和重构的风险。特别是避免那些在意想不到之处出现的 BUG。 简化系统集成。 单元测试确保了系统或模块本身的正确性集成时更不容易出错。 提高代码质量和可维护性。 不可测试的代码其本身的抽象性、模块性、可维护性是有些问题的。例如不符合单一职责、接口隔离等设计原则或者依赖了全局变量。可测试的代码往往其质量相对会高一些。 提供文档和说明。 单元测试本身就是接口使用方法的很好的案例。 持续集成和持续交付 2010 年前后大部分互联网公司的系统部署还是通过手工的方式进行的往往要在半夜上线系统。但是之后持续集成、持续交付的理念不断推广部署过程越来越灵活、顺畅。而单元测试则是持续集成和持续交付里重要的一环。 持续集成就是 Continuous IntegrationCI也就是指从开发上传代码、自动构建和测试、最后反馈结果的过程。 更进一步如果自动构建和测试后会自动发布到测试环境或预发布环境执行更多测试集成测试、自动化 UI 测试等甚至最后直接发布那这一过程就是持续交付Continuous DeliveryCD。业内有不少公司比如亚马逊、Esty可以做到每天几十甚至成百上千次生产环境部署就是因为有比较完善的持续交付环境。 CI 已经是互联网行业必备标准CD 也在互联网行业有了越来越多的实践但是如果没有单元测试这一环节CI 和 CD 的过程是有缺陷的。 怎么写单元测试 JUnit 简介 基本上每种语言和框架都有不错的单元测试框架和工具例如 Java 的 JUnit、Scala 的 ScalaTest、Python 的 unittest、JavaScript 的 Jest 等。上面的例子都是基于 JUnit 的我们下面就简单介绍下 JUnit。 JUnit 里面每个 Test 注解的方法就是一个测试。Ignore 可以忽略一个测试。Before、BeforeClass、After、AfterClass 可以在测试执行前后插入一些通用的操作比如初始化和资源释放等等。 除了 assertEqualsJUnit 也支持不少其他的 assert 方法。例如 assertNull、assertArrayEquals、assertThrows、assertTimeout 等。另外也可以用第三方的 assert 库比如 Spring 的 Assert 或者 AssertJ。 除了可以测试普通的代码逻辑JUnit 也可以进行异常测试和时间测试。异常测试是测试某段代码必须抛指定的异常时间测试则是测试代码执行时间在一定范围内。 也可以对测试进行分组。例如可以分成 contractTest 、mockTest 和 unitTest通过参数指定执行某个分组的测试。 这里就不做过多介绍了想了解更多 JUnit 的可以去看 极客学院的 JUnit 教程 等资料。其他的单元测试框架基本功能都是大同小异。 使用测试 Double 狭义的单元测试我们是只测试单元本身。即使我们写的是广义的单元测试它依然可能依赖其他模块比如其他类的方法、第三方服务调用或者数据库查询等等造成我们无法很方便的测试被测系统或模块。这时我们就需要使用测试 Double 了。 如果细究的话测试 Double 分成好多种比如什么 Dummies、Fakes 等等。但我认为我们只要弄清两类就可以了也就是 Stub 和 Mock。 Stub Stub 指那些包含了预定义好的数据并且在测试时返回给调用者的对象。Stub 常被用于我们不希望返回真实数据或者造成其他副作用的场景。 我们契约测试生成的、可以通过 spring cloud stubrunner 运行的 Stub Jar 就是一个 Stub。我们可以让 Stub 返回预设好的假数据然后在单元测试里就可以依赖这些数据对代码进行测试。例如我们可以让用户查询 Stub 根据参数里的用户 ID 返回认证用户和未认证用户然后我们就可以测试调用方在这两种情况下的处理逻辑了。 当然Stub 也可以不是远程服务而是另外一个类。所以我们经常说要针对接口编程因为这样我们就可以很容易的创建一个接口的 Stub 实现从而替换具体的类。 public class StubNameService implement NameService { public String get(String userId) { return ““Mock user name””; } } public class UserServiceTest { // UserService 依赖 NameService会调用其 get 方法 Inject private UserService userService; Test public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() { userService.setNameService(new StubNameService()); String testName userService.getUserName(““SomeId””); Assert.assertEquals(““Mock user name””, testName); } } 不过这样要实现很多 Stub 也是很麻烦的现在我们已经不需要自己创建 Stub 了因为有了各种 Mock 工具。 Mock Mocks 指那些可以记录它们的调用信息的对象在测试断言中我们可以验证 Mocks 被进行了符合期望的调用。 Mock 和 Stub 的区别在于Stub 只是提供一些数据它并不进行验证或者只是基于状态做一些验证而 Mock 除了可以做 Stub 的事情也可以基于调用行为进行验证。比如说Mock 可以验证 Mock 接口被调用了不多不少正好两次并且调用的参数是期望的数值。 Java 里最常用的 Mock 工具就是 Mockito 了。我们来看一个简单的例子下面的 UserService 依赖 NameService。当我们测试 UserService 的时候我们希望隔离 NameService那么就可以创建一个 Mock 的 NameService 注入到 UserService 中在 Spring 里只需要用 Mock 和 InjectMocks 两个注解就可以完成了 public class UserServiceTest { InjectMocks private UserService userService; Mock private NameService nameService; Test public void whenUserIdIsProvided_thenRetrievedNameIsCorrect() { Mockito.when(nameService.getUserName(““SomeId””)).thenReturn(““Mock user name””); String testName userService.getUserName(““SomeId””); Assert.assertEquals(““Mock user name””, testName); Mockito.verify(nameService).getUserName(““SomeId””); } } 注意上面最后一行是验证 nameService 的 getUserName 被调用并且参数为 ““SomeId””。 契约测试 契约测试会给每个服务生成一个 Stub可以用于调用方的单元集成测试。例如我们需要测试预约服务的预约操作而预约操作会调用用户服务去验证用户的一些基本信息比如医生是否认证等。 所以我们可以通过传入不同的用户 ID让契约 Stub 返回不同状态的用户数据从而验证不同的处理流程。例如正常的预约流程的测试用例可能是这样的。 RunWith(SpringJUnit4ClassRunner.class) SpringBootTestAutoConfigureStubRunner(repositoryRoot““http://nexus_root””, ids {“com.xingren.service:user-client-stubs:1.0.0:stubs:6565”})public class BookingTest { // BookingService 会调用用户服务获取医生认证状态后进行不同的处理 Inject private BookingService bookingService; Test public void testBooking() { BookingForm form new BookingForm( 1,// doctorId 1// scheduleId 1001);// patientId BookVO res bookingService.book(form); assertTrue(res.id 0); assertTrue(res.payStatus PayStatus.UN_PAY); } } 注意上面的 AutoConfigureStubRunner 注解就是设置并启动了用户服务 Stub当然在测试的时候我们需要把服务调用接口的 baseUrl 设置为http://localhost:6565。关于契约测试的更多内容请参考微服务环境下的集成测试探索一文。 TDD 简单说下 Test Driven Development也就是 TDD。左耳朵耗子就写了一篇TDD并不是看上去的那么美我就直接引用其介绍了。 其开发过程是从功能需求的test case开始先添加一个test case然后运行所有的test case看看有没有问题再实现test case所要测试的功能然后再运行test case查看是否有case失败然后重构代码再重复以上步骤。 其实严格的 TDD 流程实用性并不高左耳朵耗子本身也是持批判态度。但是对于接口定义比较明确的模块先写单元测试再写实现代码还是有很大好处的。因为目标清晰而且可以立刻得到反馈。 c 文章来源网络 版权归原作者所有 上文内容不用于商业目的如涉及知识产权问题请权利人联系小编我们将立即处理
http://www.zqtcl.cn/news/867867/

相关文章:

  • 网站上动画视频怎么做的建设兵团12师教育局网站
  • 博客网站开发思维导图app网站制作公司
  • 池州网站建设有哪些公司兴义网站seo
  • seo优化网站模板网站建设的七大优缺点
  • 天猫国际采取的跨境电商网络营销方式关键词排名优化公司推荐
  • 亳州建设网站做网站文字怎么围绕图片
  • 网站开发 项目计划外链建设给网站起的作用
  • 你好南京网站网站开发实施步骤和说明
  • 文化共享工程网站建设情况wordpress菠菜插件
  • 网站大气是什么意思哈尔滨做网站电话
  • 公司网站站群是什么化妆品网站设计欣赏
  • 网站公司未来计划ppt怎么做平潭做网站
  • 做网站和推广工资多少招聘网站建设价格
  • 网站建设 响应式 北京网架公司十大排名榜
  • 网站推广目标关键词是什么意思网站推广软件工具
  • 哪里可以做免费的物流网站wordpress为什么放弃
  • 做网站需要多少钱 都包括什么高端大气的网站首页
  • 黄石做网站联系最近的国际新闻
  • 网站建设与运营的预算方案淘宝禁止了网站建设类
  • 做网站的顺序编写app的软件
  • 站长联盟个人网站不备案
  • 惠州建设工程交易网站网站服务器失去响应
  • 网站下拉广告iphone app wordpress
  • 网站图片怎样做seo优化如何重新安装wordpress
  • python做网站源码长沙建设网站制作
  • wordpress调用分类的所有子目录龙岩seo公司首荐3火星
  • 聊城市建设工程质量监督站网站wordpress 头部
  • 低价郑州网站建设wordpress是外网吗
  • 互联网门户网站有哪些win10优化大师是官方的吗
  • 深圳品牌做网站公司有哪些公司名称变更网站要重新备案吗