zoukankan      html  css  js  c++  java
  • 使用“数据驱动测试”之前你应该知道的(二)

    我们继续上期的话题,单纯读取数据文件来做自动化是有诸多问题的。那么我们借助单元测试框架来做自动化就爽多了,因为它解决了测试中的几问题。

    • 如何定义一条测试用例,我们知道编程的世界里并没“用例”的概念。它只有目录、文件、类、方法、函数...,而单元测试框架告诉我们如何定义一条用例。

    • 如何写断言,是的!当你做了一堆操作之后,如何判断这一系列操作是符合预期的,那么一定要拿实际结果与预期结果进行比较,而单元测试框架告诉我们如何写断言。

    • 测试结果统计,当执行了一系列的用例之后,总共运行了多少条用例,成功了多少条,失败了多少条,失败的用例错误在哪里?单元测试框架会帮我们统计和展示。

    被测功能还是上一篇的功能。


    这里以unittest 单元测试框架为例。
    import unittest
    from selenium import webdriver
    from time import sleep
    
    class LoginTest(unittest.TestCase):
    
        @classmethod
        def setUpClass(cls):
            cls.driver = webdriver.Chrome()
            cls.url = "http://127.0.0.1:8000/"
            cls.driver.implicitly_wait(10)
    
        @classmethod
        def tearDownClass(cls):
            cls.driver.quit()
    
        def user_login(self, username, password):
            driver = self.driver
            driver.get(self.url)
            driver.find_element_by_id("inputUsername").send_keys(username)
            driver.find_element_by_id("inputPassword").send_keys(password)
            driver.find_element_by_id("Login").click()
    
        def atest_login_01(self):
            self.user_login("", '123')
            tips = self.driver.find_element_by_id("tips").text
            self.assertEqual(tips, '请输入帐号')
    
        def atest_login_02(self):
            self.user_login("user", "")
            tips = self.driver.find_element_by_id("tips").text
            self.assertEqual(tips, '请输入密码')
    
        def atest_login_03(self):
            self.user_login("error", "error")
            tips = self.driver.find_element_by_id("tips").text
            self.assertEqual(tips, '帐号或密码错误')
    
        def atest_login_04(self):
            self.user_login("admin", "admin123456")
            sleep(2)
            tips = self.driver.find_element_by_id("user").text
            self.assertEqual(tips, 'admin你好')
    
    
    if __name__ == '__main__':
        unittest.main()
    
    

    看!测试代码是不是非常清晰。运行结果如下。

    ...F
    ======================================================================
    FAIL: test_login_04 (__main__.LoginTest)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "test_login.py", line 43, in test_login_04
        self.assertEqual(tips, 'admin你好')
    AssertionError: 'admin' != 'admin你好'
    - admin
    + admin你好
    ?      ++
    
    ----------------------------------------------------------------------
    Ran 4 tests in 12.977s
    
    FAILED (failures=1)
    

    结果告诉我们运行了4条测试,1条失败了,失败的原因是test_login_04用例断言预期结果为“admin你好”,实际结果为“admin”。

    可是,这没有用到读取数据文件啊?不是,数据驱动啊? 我以为这么规范的编写测试用例,要啥自行车。

    其实,我已经尽量的把登录操作做了封装,每条用例里面只关心登录的数据和结果的断言。谁告诉你“数据驱动”就必须要“读取数据文件”的?


    我们继续引入unitest的参数化。
    import unittest
    from selenium import webdriver
    from time import sleep
    from parameterized import parameterized
    
    
    class LoginTest(unittest.TestCase):
    
        @classmethod
        def setUpClass(cls):
            cls.driver = webdriver.Chrome()
            cls.url = "http://127.0.0.1:8000/"
            cls.driver.implicitly_wait(10)
    
        @classmethod
        def tearDownClass(cls):
            cls.driver.quit()
    
        def user_login(self, username, password):
            driver = self.driver
            driver.get(self.url)
            driver.find_element_by_id("inputUsername").send_keys(username)
            driver.find_element_by_id("inputPassword").send_keys(password)
            driver.find_element_by_id("Login").click()
    
        @parameterized.expand([
            ("user_null", '', "123", "请输入帐号"),
            ("pawd_null", "user", '', "请输入密码"),
            ("login_error", "error", "error", "帐号或密码错误"),
            ("login_success", "admin", "admin123456", "admin你好"),
        ])
        def test_login(self, name, username, password, assert_text):
            self.user_login(username, password)
            if name == "login_success":
                sleep(2)
                tips = self.driver.find_element_by_id("user").text
                self.assertEqual(tips, assert_text)
            else:
                tips = self.driver.find_element_by_id("tips").text
                self.assertEqual(tips, assert_text)
    
    
    if __name__ == '__main__':
        unittest.main(verbosity=2)
    

    反正都是定义测试数据,这里提供了规范的元组给你用来定义数据,而且测试数据与测试方法上下呼应,维护起来也比读取文件方便多了,这次还要啥自行车?

    测试结果:

    test_login_0_user_null (__main__.LoginTest) ... ok
    test_login_1_pawd_null (__main__.LoginTest) ... ok
    test_login_2_login_error (__main__.LoginTest) ... ok
    test_login_3_login_success (__main__.LoginTest) ... FAIL
    
    ======================================================================
    FAIL: test_login_3_login_success (__main__.LoginTest)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "C:Python36libsite-packagesparameterized-0.6.1-py3.6.eggparameterizedparameterized.py", line 392, in standalone_func
        return func(*(a + p.args), **p.kwargs)
      File "test_login.py", line 37, in test_login
        self.assertEqual(tips, assert_text)
    AssertionError: 'admin' != '请输入密码'
    - admin
    + 请输入密码
    
    ----------------------------------------------------------------------
    Ran 4 tests in 12.363s
    
    FAILED (failures=1)
    

    测试结果依然清晰明白。

    这个话题,本来到此就结束了,我其实是很鄙视读取数据文件的操作的,因为真get不到它的“方便”之处,做自动化测试写代码就老老实实的写代码,就你测试用的这点数据,真没必要读取文件,数据库就更谈不上了。但是,那么多人都在分享读取数据文件的demo(实际规模化之后就不得而知了),我也看了不少资料,找到一些勉强能接受的方法。

    当然,这又是另一篇文章了。

  • 相关阅读:
    lecture 11.4
    lecture 10.30
    boolean functions and beyon
    lecture10.21
    golang hex to string
    golang中 将string转化为json
    ubuntu16报错: add-apt-repository command not found
    ubuntu16的防火墙关闭
    ubuntu 16 解决错误 manpath: can't set the locale; make sure $LC_* and $LANG are correct
    go get 安装时报 (https fetch: Get https://golang.org/x/crypto/acme/autocert?go-get=1: dial tcp 220.255.2.153:443: i/o timeout)
  • 原文地址:https://www.cnblogs.com/fnng/p/9426844.html
Copyright © 2011-2022 走看看