zoukankan      html  css  js  c++  java
  • 软件工程第二次作业

    (一)选择开发工具

    本次作业我选择了python语言作为开发工具,以前虽然没有学习过,但是这两年可能该语言使用比较多,学校这学期的课程也多要求自学python并使用,所以也借着学习这学期课程的机会尝试选择了一下python,选择的开发工具是pycharm。软件截图如下:
    

    (二)Python单元测试框架

    unittest核心工作原理

     unittest中最核心的四个概念是:test case, test suite, test runner, test fixture。
    

    一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。

    多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。

    TestLoader是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。

    TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。 测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。

    而对一个测试用例环境的搭建和销毁,是一个fixture。

    基本测试实例

    使用python3.7.3编写一个单元测试demo,我们先来准备一些待测方法:
    
    mathfunc.py
    def add(a, b):
       return a+b
    
    def minus(a, b):
        return a-b
    
    def multi(a, b):
        return a*b
    
    def divide(a, b):
        return a/b
    

    接下来我们为这些方法写一个测试:

    test_mathfunc.py
    import unittest
    from mathfunc import *
    
    class TestMathFunc(unittest.TestCase):
        """Test mathfuc.py"""
    
        def test_add(self):
            """Test method add(a, b)"""
            self.assertEqual(3, add(1, 2))
            self.assertNotEqual(3, add(2, 2))
    
        def test_minus(self):
            """Test method minus(a, b)"""
            self.assertEqual(1, minus(3, 2))
    
        def test_multi(self):
            """Test method multi(a, b)"""
            self.assertEqual(6, multi(2, 3))
    
        def test_divide(self):
            """Test method divide(a, b)"""
            self.assertEqual(2, divide(6, 3))
            self.assertEqual(2.5, divide(5, 2))
    
    if __name__ == '__main__':
        unittest.main()
    

    执行结果截图如下:

    能够看到一共运行了4个测试,运行均成功。
    这就是一个简单的测试,有几点需要说明的:
    在第一行给出了每一个用例执行的结果的标识,成功是 .,失败是 F,出错是 E,跳过是 S。从上面也可以看出,测试的执行跟方法的顺序没有关系,test_divide写在了第4个,但是却是第2个执行的。

    每个测试方法均以 test 开头,否则是不被unittest识别的。

    在unittest.main()中加 verbosity 参数可以控制输出的错误报告的详细程度,默认是 1,如果设为 0,则不输出每一用例的执行结果;如果设为 2,则输出详细的执行结果。
    结果如下截图:

    组织TestSuite

    上面的代码示例了如何编写一个简单的测试,但有两个问题,我们怎么控制用例执行的顺序呢?(这里的示例中的几个测试方法并没有一定关系,但之后你写的用例可能会有先后关系,需要先执行方法A,再执行方法B),我们就要用到TestSuite了。我们添加到TestSuite中的case是会按照添加的顺序执行的。

    问题二是我们现在只有一个测试文件,我们直接执行该文件即可,但如果有多个测试文件,怎么进行组织,总不能一个个文件执行吧,答案也在TestSuite中。

    下面来举个例子:

    在文件夹中我们再新建一个文件,test_suite.py:

     -*- coding: utf-8 -*-
    import unittest
    from test_mathfunc import TestMathFunc
    
    if __name__ == '__main__':
        suite = unittest.TestSuite()
    
        tests = [TestMathFunc("test_add"), TestMathFunc("test_minus"), TestMathFunc("test_divide")]
        suite.addTests(tests)
    
        runner = unittest.TextTestRunner(verbosity=2)
        runner.run(suite)
    

    执行结果如下:

    注意,用TestLoader的方法是无法对case进行排序的,同时,suite中也可以套suite。

    将结果输出到文件中

    用例组织好了,但结果只能输出到控制台,这样没有办法查看之前的执行记录,我们想将结果输出到文件。

    修改test_suite.py:

     -*- coding: utf-8 -*-
    
    import unittest
    from test_mathfunc import TestMathFunc
    
    if __name__ == '__main__':
        suite = unittest.TestSuite()
        suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc))
    
        with open('UnittestTextReport.txt', 'a') as f:
            runner = unittest.TextTestRunner(stream=f, verbosity=2)
            runner.run(suite)
    

    执行此文件,可以看到,在同目录下生成了UnittestTextReport.txt,所有的执行报告均输出到了此文件中,这下我们便有了txt格式的测试报告了。
    结果如下图:

    总结

    unittest是python自带的单元测试框架,我们可以用其来作为我们自动化测试框架的用例组织执行框架。
    unittest的流程:写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,我们通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者我们可以直接通过TextTestRunner来执行用例。
    一个class继承unittest.TestCase即是一个TestCase,其中以 test 开头的方法在load时被加载为一个真正的TestCase。
    verbosity参数可以控制执行结果的输出,0 是简单报告、1 是一般报告、2 是详细报告。
    另外可以用 setUp()、tearDown()、setUpClass()以及 tearDownClass()可以在用例执行前布置环境,以及在用例执行后清理环境,也可以通过skip,skipIf,skipUnless装饰器跳过某个case,或者用TestCase.skipTest方法。

  • 相关阅读:
    破解Mac版MyEclipse-2017-ci3
    JAVA8 十大新特性详解
    Java 1.8 时间日期库的20个使用示例
    20180206 反射中模块化开发的上课思路
    反射在数据库读写中的应用
    浅谈多线程并发
    Mac OS Git 安装
    MAC node + git + bower 简单安装
    Mac OS 下 eclipse中文乱码解决方法(eclipse for mac 中文乱码)
    【精华】MacOS 10.13.2 环境下安装eclipse
  • 原文地址:https://www.cnblogs.com/liuch03/p/10699479.html
Copyright © 2011-2022 走看看