博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
你会写单元测试吗
阅读量:6536 次
发布时间:2019-06-24

本文共 3451 字,大约阅读时间需要 11 分钟。

关于我

编程界的一名小小程序猿,目前在一个创业团队任team lead,技术栈涉及Android、Python、Java和Go,这个也是我们团队的主要技术栈。 联系:hylinux1024@gmail.com

也许你已经听说过Test Driven Development,但不知道你是否遵循这个规则呢?其实我自己在写代码的时候也很少会先写单元测试再写业务功能逻辑。这不我也今天也来学习如何在Python中写单元测试。

0x00 unittest

Python中的unittest单元测试框架跟其它语言如JUnit是类似的。它支持测试自动化、配置共享以及关机代码测试。

假设在我的项目目录下有一个mysum模块用于计算列表中各个数之和。 还有一个test_mysum.py用于编写单元测试的文件。

myproject/│├── mysum/│   └── __init__.py└── unittests    └── test_mysum.py复制代码

打开mysum模块中的__init__.py文件。

添加下面的方法

def sum(args):    total = 0    for arg in args:        total += arg    return total复制代码

打开test_mysum.py,编写单元测试

import unittestfrom mysum import sumclass TestSum(unittest.TestCase):    def test_list_int(self):        """        测试一个整数列表的和        """        data = [1, 2, 3]        result = sum(data)        self.assertEqual(result, 6)if __name__ == '__main__':    unittest.main()复制代码

首先导入我们要测试的模块mysum 测试用例类通过继承unittest.TestCase来实现,测试方法test_list_int是以test开头的。 在这个方法中定义了一个整型列表,执行sum方法,然后判断执行结果是否与预期相符。

最后调用unittest.main()来执行这个测试用例

Ran 1 test in 0.001sOK复制代码

如果再添加一个方法

def test_list_sum(self):    data = [1, 3, 4]    result = sum(data)    self.assertEqual(result, 6)复制代码

执行后会看到如下类似信息

6 != 8Expected :8Actual   :6复制代码

从这个输出信息可以看出期望值与实际值不相符,这时候如果我们的测试用例没有问题,那就要看看mysum的实现逻辑了。

从这个例子中可以总结一个测试用例的过程:

  1. 构建输入数据
  2. 执行要测试模块,获取执行结果
  3. 与预期结果相比较,根据结果修改代码

0x01 setup/tearDown

在编写单元测试时,还可以重写父类的setuptearDown方法,可以在执行测试逻辑开始前和结束时做一些处理。例如在setup方法中可以初始化测试数据,在tearDown方法做一些清理工作。

import unittestclass TestBasic(unittest.TestCase):    def setUp(self):        # 加载测试数据        self.app = App(database='fixtures/test_basic.json')    def test_customer_count(self):        self.assertEqual(len(self.app.customers), 100)    def test_existence_of_customer(self):        customer = self.app.get_customer(id=10)        self.assertEqual(customer.name, "Org XYZ")        self.assertEqual(customer.address, "10 Red Road, Reading")        def tearDown(self):        self.app.releaseDB()复制代码

在每个测试执行时setuptearDown都会被执行一次。

0x02 pytest

pytest是一个第三方测试框架,使用它不需要继承某个类,它可以使用原生的assert语句用于测试结果的断言。

它的用法也很简单

首先通过pip安装

➜ pip install pytest复制代码

我们写一个单独的tests文件夹下创建测试用例文件test_pytest.py。 注意:这里pytest的文件必须与上文的unittests文件必须区分开,否则会出现ModuleNotFoundError。我已经在这里踩坑。

我这里使用pytest单元测试的文件结构为

tests│└── test_func.py复制代码

test_func.py的内容为

# 导入我们要测试的模块from mysum import sumdef test_answer():    data = [1, 2, 3]    assert sum(data) == 5复制代码

测试方法以test开头

然后再命令行中执行

➜ python -m pytest tests/test_func.py 复制代码

注意:这里要使用python -m pytest,如果直接使用pytest会提示ModuleNotFoundError: No module named 'mysum'

执行结果如下

tests/test_func.py F                                                                                                                                                                          [100%]======================================================= FAILURES ==============================================_______________________________________________________ test_answer ___________________________________________    def test_answer():        data = [1, 2, 3]    >       assert sum(data) == 5E       assert 6 == 5E        +  where 6 = sum([1, 2, 3])tests/test_func.py:11: AssertionError=======================================================1 failed in 0.03 seconds =======================================================复制代码

由于6!=5,这个单元测试提示了出错的位置。

0x03 总结一下

测试代码对编写代码非常重要,写单元测试也是一个好习惯。本文也只是一个开胃菜。要写出健壮的代码,从写单元测试开始吧。

0x04 学习资料

  • Unit testing framework
  • Getting Started With Testing in Python
  • Testing Your Code

转载于:https://juejin.im/post/5d01a541e51d45554877a5b6

你可能感兴趣的文章
图解openssl实现私有CA
查看>>
BZOJ2213 : [Poi2011]Difference
查看>>
c++ Constructor FAQ 继续
查看>>
事务之六:spring 嵌套事务
查看>>
C#:路径
查看>>
iOS图片加载速度极限优化—FastImageCache解析
查看>>
PHP中的一些新特性
查看>>
I.MX6 Android mmm convenient to use
查看>>
[CareerCup] 13.9 Aligned Malloc and Free Function 写一对申请和释放内存函数
查看>>
Stack and Heap 堆和栈的区别
查看>>
什么是 A 轮融资?有 B轮 C轮么?
查看>>
55、Android网络图片 加载缓存处理库的使用
查看>>
svn文件提交时强制写注释
查看>>
【转载】千万级规模高性能、高并发的网络架构经验分享
查看>>
OC基础--OC中的类方法和对象方法
查看>>
ubuntu samba服务器多用户配置【转】
查看>>
母线的种类与作用是什么(转)
查看>>
【Xamarin 挖墙脚系列:IOS 开发界面的3种方式】
查看>>
Atitit.工作流系统的本质是dsl 图形化的dsl 4gl
查看>>
I.MX6 Android USB Touch eGTouchA.ini文件存放
查看>>