测试用例怎么样写?怎么搞懂方法和流程?

前言

作为一个测试新人,刚开始接触测试,对于怎么写测试用例很头疼,无法接触需求,只能根据站在用户的角度去做测试,但是这样情况会导致不能全方位的测试APP,这种情况就需要一份测试用例了,但是不会写,求指教!还有就是测试出来的bug该如何追踪?与开发的接触基本上面对面的交流,没有很好的一个规范

一、什么是测试用例

测试用例:为了特定的目的(证明软件存在某问题)而设计的一组由测试输入、执行条件、预期结果构成的文档

1、测试用例简单来说就是指导如何做测试的文档,该文档主要记录需要验证被测软件的是否满足需求

2、测试用例表现形式常见的有两种,可以以模板形式展示

1)一种是通过Excel直接编写

——大多数项目中都需要按照这种方式设计编写

2)一种是通过xmind直接整理测试点

——时间紧迫,项目没有强制要求时,可以设计测试点的形式编写
——对于业务流程类的测试,也可以整理为测试点进行测试

3、设计及执行人员:测试工程师

4、用例的模板:描述编写用例核心内容,一般项目都有自己的设计用例的模板

二.为什么要写测试用例

为什么要写测试用例,实际中产品出现问题,第一责任人首先想到的是测试为啥没有测到?

产品出现问题了,你为啥没有测出来呢?

当然,除了避免“甩锅和背锅”,其实写测试用例更重要的作用如下:

        技术上将需求转化为具体可验证的指标

        以文档的形式记录软件可能存在的问题

        防止测试过程的活动出现遗漏,提高工作效率

        测试工作量的展示

三.如何编写测试用例

既然写测试用例如此重要,那么如何更好的编写测试用例呢?个人认为需要满足如下几点: - 常规思考,设身处地的从用户角度出发(比如:实际用户是这么使用的么,会不会遇到异常情况呢?) - 测试理论方法的支撑(比如:根据需求设计测试用例时,能用到哪些常见的测试用例设计方法?) - 产品的熟悉和经验的积累(比如:已经有过类型项目经验,曾经在某个方面有过问题,当时是如何处理的呢?) 上述的设计用例过程,有个前提,就是对于测试有耐心和毅力,加上日常有意识的思维训练,才会写出全面的用例

测试函数

首先是给出用于测试的代码,如下所示,这是一个接收姓和名然后返回整洁的姓名的函数:

def get_formatted_name(first, last):
    full_name = first + ' ' + last
    return full_name.title()

简单的测试代码:

first = 'kobe'
last = 'bryant'
print(get_formatted_name(first, last)) # 输出 Kobe Bryant

在 Python 标准库中的模块 unittest 提供了代码测试工具。这里介绍几个名词的含义:

        单元测试:用于核实函数的某个方面没有问题;

        测试用例:一组单元测试,它们一起核实函数在各种情形下的行为符合要求。

        全覆盖式测试用例:包含一整套单元测试,涵盖了各种可能的函数使用方式。

通常,最初只需要对函数的重要行为编写测试即可,等项目被广泛使用时才考虑全覆盖。

接下来就开始介绍如何采用 unittest 对代码进行测试。

首先是需要导入 unittest 模块,然后创建一个继承 unittest.TestCase 的类,并编写一系列类方法对函数的不同行为进行测试,如下代码所示:

import unittest
 
class NamesTestCase(unittest.TestCase):
    '''
    测试生成名字函数的类
    '''
 
    def test_first_last_name(self):
        formatted_name = get_formatted_name('kobe', 'bryant')
        self.assertEqual(formatted_name, 'Kobe Bryant')
        
unittest.main()

输出结果如下,显示运行的测试样例是 1 个,耗时是 0.001s。

.
----------------------------------------------------------------------
Ran 1 test in 0.001s
 
OK

上述是给了一个可以通过的例子,而如果测试不通过,输出是怎样的呢,如下所示:

# 添加中间名
def get_formatted_name(first, middel, last):
    full_name = first + ' ' + middle + ' ' + last
    return full_name.title()
 
class NamesTestCase(unittest.TestCase):
    '''
    测试生成名字函数的类
    '''
	# 不能通过的例子
    def test_first_name(self):
        formatted_name = get_formatted_name('kobe', 'bryant')
        self.assertEqual(formatted_name, 'Kobe Bryant')
                
unittest.main()

输出结果如下,这里会打印错误发生的地方和错误原因:

E
======================================================================
ERROR: test_first_last_middle_name (__main__.NamesTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "E:/Python_Notes/Practise/unittest_practise.py", line 39, in test_first_last_middle_name
    formatted_name = get_formatted_name('kobe', 'bryant')
TypeError: get_formatted_name() missing 1 required positional argument: 'middle'
 
----------------------------------------------------------------------
Ran 1 test in 0.001s
 
FAILED (errors=1)
复制代码

很明显是因为缺少 middle 参数,如果希望通过测试,可以将原函数进行如下修改:

def get_formatted_name(first, last, middle=''):
    '''
    接收姓和名然后返回完整的姓名
    :param first:
    :param last:
    :return:
    '''
    if middle:
        full_name = first + ' ' + middle + ' ' + last
    else:
        full_name = first + ' ' + last
    return full_name.title()
复制代码

然后添加新的测试方法,继续运行,就可以测试通过。

def test_first_last_middle_name(self):
    formatted_name = get_formatted_name('kobe', 'bryant', 'snake')
    self.assertEqual(formatted_name, 'Kobe Snake Bryant')

测试类

上一小节介绍了给函数写测试的代码,接下来介绍如何编写针对类的测试。

断言方法

在 unitest.TestCase 类中提供了很多断言方法,上一小节就采用了 assertEqual 这一个判断给定两个参数是否相等的断言方法,下面给出常用的 6 个断言方法:

方法用途
assertEqual(a, b)核实 a == b
assertNotEqual(a, b)核实 a != b
assertTrue(x)核实 x 是 True
assertFalse(x)核实 x 是 False
assertIn(item, list)核实 item 在 list 中
assertNotIn(item, list)核实 item 不在 list 中

这些方法都只能在继承了 unittest.TestCase 的类中使用这些方法。

编写针对类的测试

首先,编写用于进行测试的类,代码如下所示,这是一个用于管理匿名调查问卷答案的类:

class AnonymousSurvey():
    '''
    收集匿名调查问卷的答案
    '''
 
    def __init__(self, question):
        '''
        :param question:
        '''
        self.question = question
        self.responses = []
    
    def show_question(self):
        '''
        显示问卷
        :return: 
        '''
        print(self.question)
    
    def store_response(self, new_response):
        '''
        存储单份调查问卷
        :param new_response: 
        :return: 
        '''
        self.responses.append(new_response)
    
    def show_results(self):
        '''
        显示所有答卷
        :return: 
        '''
        print('Survey results:')
        for response in self.responses:
            print('- ' + response)
   
复制代码

 这个类包含三个方法,分别是显示问题、存储单份问卷以及展示所有调查问卷,下面是一个使用例子:

def use_anonymous_survey():
    question = "世上最好的语言是?"
    language_survey = AnonymousSurvey(question)
    # 显示问题
    language_survey.show_question()
    # 添加问卷
    language_survey.store_response('php')
    language_survey.store_response('python')
    language_survey.store_response('c++')
    language_survey.store_response('java')
    language_survey.store_response('go')
    # 展示所有问卷
    language_survey.show_results()
 
 
if __name__ == '__main__':
    use_anonymous_survey()
复制代码

输出结果如下:

世上最好的语言是?
Survey results:
- php
- python
- c++
- java
- go

然后就开始编写对该类的测试代码,同样创建一个类,继承 unittest.TestCase ,然后类方法进行测试,代码如下所示:

import unittest
 
class TestAnonmyousSurvey(unittest.TestCase):
 
    def test_store_single_response(self):
        '''
        测试保存单份问卷的方法
        :return:
        '''
        question = "世上最好的语言是?"
        language_survey = AnonymousSurvey(question)
        language_survey.store_response('php')
 
        self.assertIn('php', language_survey.responses)
unittest.main()

最后,在 unittest.TestCase 中其实包含一个方法 setUp() ,它的作用类似类的初始化方法 __init()__,它会在各种以 test_ 开头的方法运行前先运行,所以可以在这个方法里创建对象,避免在每个测试方法都需要创建一遍,所以上述代码可以修改为:

class TestAnonmyousSurvey(unittest.TestCase):
 
    def setUp(self):
        '''
        创建一个调查对象和一组答案
        :return:
        '''
        question = "世上最好的语言是?"
        self.language_survey = AnonymousSurvey(question)
        self.responses = ['c++', 'php', 'python']
 
    def test_store_single_response(self):
        '''
        测试保存单份问卷的方法
        :return:
        '''
        self.language_survey.store_response(self.responses[1])
 
        self.assertIn('php', self.language_survey.responses)
 
    def test_store_three_response(self):
        for response in self.responses:
            self.language_survey.store_response(response)
 
        for response in self.responses:
            self.assertIn(response, self.language_survey.responses)
 

运行后,输出结果如下:

..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
 
OK

注意,这里运行成功,打印一个句号,因为是运行两个测试方法成功,所以打印了两个句号;如果运行出错,打印一个 E ;测试导致断言失败,打印一个 F 。

四、总结

z此时的你再回过头来看看,还会认为登录这个百试不爽的功能就设计十几条甚至几十条测试用例了吗?显然不是那么简单,需要在熟悉需求基础上,进行拆分细化,将常规的思考、经验的积累、理论的支撑结合起来使用,最终才能转化为测试待验证的结果。

 

感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取   

测试用例的编是确保软件产品质量可控的重要步骤。下面是编测试用例的一般步骤: 1. 确定测试目标:明确测试的目的和范围,以便有针对性地编测试用例。 2. 定义测试条件:根据需求和设计文档,确定测试的输入条件、环境条件和预期结果。 3. 编测试用例:根据测试条件,编测试用例,包括测试步骤和预期结果。个测试用例应该只测试一个功能点或场景,并保持简洁明了。 4. 确定测试数据:根据测试用例的需求,准备适当的测试数据,包括正常数据、边界数据和异常数据。 5. 执行测试用例:按照测试用例的步骤执行测试,记录实际结果。 6. 比较实际结果和预期结果:将实际结果与预期结果进行比较,判断测试是否通过。 7. 记录测试结果:记录测试用例的执行结果,包括通过、失败或有缺陷。 8. 分析测试结果:根据测试结果进行分析,找出失败的原因,并提交缺陷报告。 9. 优化测试用例:根据测试结果和反馈,不断优化测试用例,提高测试的覆盖率和效率。 10. 定期回顾测试用例:定期回顾测试用例,确保测试用例的准确性和完整性。 总结起来,编测试用例需要明确测试目标、定义测试条件、编测试用例、确定测试数据、执行测试用例、比较实际结果和预期结果、记录测试结果、分析测试结果、优化测试用例和定期回顾测试用例。这样可以确保测试用例的质量和可控性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值