单元测试PHPUnit入门三板斧

简介: 什么,你是程序员?什么你从来没写过单元测试用例?嗯,不要惊讶,这在国内正常的啦。有的觉得写这个玩意太耗时间了,有的干脆就不知道单元测试用例是怎么玩的。说来惭愧,小马也是在CICD的“胁迫”下开始正式涉足。

啥是单元测试

百度百科是这么说的:

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

还别说,说得还挺在理。注意这里的人为规定的最小可测单位,意思是说其实不同情况下可测单元是人为规定没有统一规范的。也就是,如果是一个框架的控制器class,对它来写单元测试的话,打桩和mock的东西就会非常多,这种的通常情况下就不适合做单元测试,要做的单元测试一般是单一职责的class或者函数。

小马就以PHP来展开吧。PHP单元测试框架也比较多,下面就拿比较主流的PHPUnit来起飞吧。

第一斧:PHPunit安装

要使用PHPunit,首先肯定是安装,安装有两种比较简单的方式:php档案包(phar)和composer。小马就使用composer安装的PHPunit,安装过程还是比较简单的。小马在安装方面之前已经有相关文章了,这里就不再赘述了,可以参看文章《单元测试PHPUnit初体验之安装与示例》。

第二斧:IDE配置支持PHPunit

因为我们基于IDE开发PHP项目,于是就想也基于IDE直接运行我们的测试用例,所以才有了这一板斧。意思是对IDE配置完之后,我们可以不用到命令行窗口执行php phpunit.phar 或phpunit命令来运行测试用例class,而是直接使用IDE提供的菜单点击run即可运行用例,十元一个非常甜非常甜,啊,不是,非常方便。下面我们就以PHPstorm为例来讨论下怎么配置IDE支持单元测试。

在讨论配置之前,我们必须先来统一下共识。phpunit框架编写的测试用例class执行方式有两种:

1、命令行窗口执行

cmd下用已全局安装的命令(PHPunit或php phpunit.phar)到测试文件目录下直接执行测试class文件即可(命令执行等同于自动加载了测试框架)。

2、用IDE支持直接右键run运行测试class文件

前提是IDE要配置自动加载测试框架的代码才可以直接run,可以理解为直接run的话需要加载一下测试框架才能跑起来测试框架代码。

好了,如果以上看不懂不要紧,我们继续往下看具体是如何配置的,或许会柳暗花明呢。

打开phpstorm,file->settings->Languages & Frameworks->PHP,我们配置我们的PHP版本;然后进入PHP->Debug->Test Frameworks配置我们的 PHPUnit Lib。这个一点注意了,这里三种方式。我们先选第二种path to phpunit.phar,然后底下自然要选我们的安装目录下的phpunit.phar文件了,然后发现并没有phpunit.phar文件,只有phpunit和phpunit.bat。这就奇怪了,难道composer安装方式没有phpunit.phar文件吗?不管了,先下载一个phpunit.phar配置进去看看。于是跑起来,嘿嘿,果然想得美,报错了。
image.png

小马立马去下载了对应版本的phpunit.phar文件(版本对应表,各版本文件下载),再跑一下看看。
image.png

image.png

此时不报版本问题了,而是报的测试框架类找不到。是不是第二种path to phpunit.phar的方式不好使呢?小马也没有去深究,直接换成第一种自动加载的方式use Composer autoloader。于是这个时候自然是要配置到我们安装目录下的自动加载文件\vendor\autoload.php。如下。

image.png

然后我们右键执行一下class文件,这一步超爽。

image.png
image.png


这里被测函数代码是return Hello


哇塞,我们看到运行成功的结果了!也就是说直接IDE的run支持必须在配置那里配置自动加载框架,否则run会报错找不到测试框架class,在用例里写自动加载代码也run不了!有机灵鬼的同学说了,如果此时我就是不想用配置自动加载的方式呢?行,那就不要用IDE直接run了,自己去cmd跑phpunit命令也可以(其实跑命令等同于加载了框架)。值得一提的是,cmd直接运行是没进入被测项目框架的(或者是因为原框架自动加载在cli下不被支持导致),原本项目 class如有依赖的类文件要在用例中重新自行包含。

总结:如果我们配置了自动加载框架文件,就直接run吧,不用再去命令行了。当然要是想直接取命令行执行也行,其实效果是一样的,命令相当于自动加载,只是有些未知问题要注意下即可。

第三斧:写单元测试用例

上面我们其实先介绍了配置,但其实我们跑了一个用例,我们还没介绍。接下来来探讨下用例该怎么写。

写测试用例其实还依赖于被测代码的可测性(如何写可测性代码),如果被测代码类之间的耦合比较高,那单元测试用例写起来也是相当头疼,所以,单元测试不仅是保证代码质量其实还从侧面降低了代码的耦合度。

如果是测试驱动型开发过程,那可能就是先写单元测试用例再写功能代码呢。写功能代码的时候,你就会考虑这样写是否可以比较方便地mock,是不是输入和输出都是可控的,每个单元是不是单一职责。

比如控制反转就是一种简单却又非常有用的解耦代码技巧,特别适合单元测试。毕竟,保持松散耦合对于能够彼此独立地分析各个单元至关重要。IoC的关键点是将控制代码(when to do something)与执行代码分开(what to do when things happen)。该技术提高了程序的灵活性,使我们的代码更加模块化,并减少了组件之间的耦合。关于怎么写出可测性代码这里就不赘述了,我们还是回到正题,看下测试用例该怎么写,关于测试框架的语法教程请先参看官方文档。来看一个例子。

我们先来看一个需要被测试的功能代码:
image.png

注意了,我们来写对于上面这个class的方法的测试用例。在我们的项目目录下新建一个目录Testcase,并新建class文件CommonLibCommonTest.php,编写测试方法testFunctionTest。这里class的Test和方法的test是规范,需要注意一下。
image.png

注意文件头的处理,这里IDE配置了自动加载可以不用加载自动加载文件就可以,但如果没有在IDE中执行呢?自然,命名执行相当于加载可以不用,但是其他方式执行呢?是不是就是要保证加载框架了?这个点留给观者自行思考。另外,如果框架载入不用use命名空间,像代码中注释的直接继承框架中的类名PHPUnit_Framework_TestCase也是可行的。
image.png

这例子用了两种断言和数据供给器


然后我们来run一下:
image.png

OK,测试执行成功了!

最后不得不提醒的是,如果包含进来的被测class文件是有定义命名空间的,在测试用例中调用必须带上命名空间,否则无法找到类,如new \CommonLib\Common()。另外,如果测试用例中new的一个实例本身有继承父类,且有定义了命名空间,则这个父类将不被找到(这个也就是为什么这种本身有继承父类的class不建议来写单元测试用例)。

单元测试PHPunit入门三板斧就到这了,本文只是入门,很多复杂的待一起进步,比如我们要测试DB要怎么写用例呢?虽然这里只是入门但是大差不差,循序渐进即可。具体的测试用例编写框架语法还是建议通读一下官方教程。谢谢品阅,欢迎指点。

相关文章
|
2月前
|
测试技术 持续交付 开发者
探索自动化测试的无限可能:从入门到精通
在软件开发领域,确保产品质量是至关重要的。自动化测试作为一种高效、可靠的测试方法,正逐渐成为行业标准。本文将带你深入了解自动化测试的世界,从基础概念到实践技巧,帮助你掌握这一强大的工具。无论你是初学者还是有经验的开发者,都能从中获得宝贵的知识和启发。
|
2月前
|
Java 测试技术 开发者
初学者入门:掌握单元测试的基础与实践
【10月更文挑战第14天】单元测试是一种软件测试方法,它验证软件中的最小可测试单元——通常是单独的函数或类——是否按预期工作。单元测试的目标是确保每个模块在其自身范围内正确无误地运行。这些测试应该独立于其他模块,并且应该能够反复执行而不受外部环境的影响。
57 2
|
4月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
22天前
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
64 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
5月前
|
测试技术 API 数据库
Django测试入门:打造坚实代码基础的钥匙
Django测试入门:打造坚实代码基础的钥匙
45 3
|
18天前
|
Java 测试技术 Android开发
探索自动化测试的奥秘:从入门到精通
【10月更文挑战第37天】本文将带你进入自动化测试的世界,从基础知识到实战案例,逐步揭示自动化测试的神秘面纱。我们将一起探讨如何利用代码来简化测试过程,提高效率,并确保软件质量。无论你是初学者还是有经验的开发者,这篇文章都能为你提供有价值的见解和技巧。让我们一起踏上这段探索之旅吧!
|
23天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
2月前
|
测试技术 网络安全
什么是软件测试? 软件测试都有什么岗位 ?软件测试和调试的区别? 软件测试和开发的区别? 一位优秀的测试人员应该具备哪些素质? 软件测试等相关概念入门篇
文章全面介绍了软件测试的基本概念、目的、岗位分类、与开发和调试的区别,并阐述了成为优秀测试人员应具备的素质和技能。
211 1
什么是软件测试? 软件测试都有什么岗位 ?软件测试和调试的区别? 软件测试和开发的区别? 一位优秀的测试人员应该具备哪些素质? 软件测试等相关概念入门篇
|
3月前
|
Web App开发 JavaScript Java
自动化测试的利剑:Selenium WebDriver入门与实践
【9月更文挑战第21天】在软件开发的海洋中,自动化测试犹如一艘船,帮助开发者们快速航行至质量保证的彼岸。本文将作为你的罗盘,指引你了解和掌握Selenium WebDriver这一强大的自动化测试工具。通过深入浅出的方式,我们将探索Selenium WebDriver的基本概念、安装过程以及编写简单测试脚本的方法。无论你是刚接触自动化测试的新手,还是希望提升测试技能的开发者,这篇文章都将为你提供有价值的指导。
|
3月前
|
Web App开发 Java 测试技术
自动化测试的利器:Selenium WebDriver入门与实践
【9月更文挑战第8天】在软件开发的海洋中,测试是确保我们不会溺水的那根救生索。Selenium WebDriver,作为自动化测试的明星工具,让这根救生索更加结实可靠。本文将带你快速上手Selenium WebDriver,从基础设置到实际操作,再到实战演练,让你的开发之旅更加平稳顺畅。