手工执行:
写用例-执行用例并记录-生成测试报告
代码执行用例:
代码表达用例
代码收集用例
代码执行用例
用代码生成测试报告
自动化用例有以下的几个内容:
1.用例的名称以text_开头
例如:
def text_hh():
assert True
2.用例的步骤:代码
3.进行断言。就是将预期结果与实际结果进行比对,如果一致则断言成功,用例通过。如果不一致则断言失败,用例不通过。
4.前置和后置。前置条件就是进行数据的准备工作,后置就是进行数据的清理操作。
(PS:对于用例来说,只要符合命名规范就是一个用例,不是一定要有断言这部分)
自动发现用例的机制:
**1.**根据rootdir
,rootdir
是代表一个目录,它代表的目录是开始搜索用例的入口,即在该目录下开始搜索用例。
那么怎么判断rootdir
呢?
第一种:使用cmd
命令行,前面的文件目录就是它的rootdir
例如:
它的rootdir
就是C:\Users\brave\PycharmProjects
第二种:在Pycharm
的main文件中先导入pytest
,然后输入pytest.main(['-v'])
,此方式的rootdir
就是指main
文件在哪个目录,它在哪个目录哪个目录就是rootdir
PS:命令行中输入的pytest -v
和文件中输入的pytest.main(['-v'])
都是将用例的执行过程更加详细的展示出来
**2.**对于文件的命名有一定的要求,不符合命名规范的文件会自动被认为里面是没有测试用例的,只会去扫描符合命名规范的文件。要求:要以test_
开头或者以_test
结尾,但是大多数情况下会选择第一种,因为按照人们的阅读习惯,是从左至右的,所以最好使用第一种。
**3.**但是并不是一个以test_
开头的文件或者是以_test
结尾的文件里面的内容全都是测试用例,对于文件里面的内容也需要进行判断。所以它会去扫描以test_开头的测试函数或者说是测试方法,并扫描那些以Test开头的测试类下面以test_
开头的测试函数
pytest
的作用:收集用例并且执行用例,加参数生成测试报告
如何判断用例执行的顺序?
对于外部的文件来说:按照名字的先后排序来判断——根据ascii
码(0-9,a-z,A-Z),越小的优先级越大,比如01就比02大,如果想要某个文件中的用例优先执行,可以通过改变文件的名称来实现。
对于文件即一个模块而言:应该按照代码的顺序从上往下执行
如果想单独执行某个py
文件应该怎么办?
例如:
此处的main.py
文件在pythonProject2
目录下面,所以说该目录就是rootdir
,如果在该文件的main.py
中进行用例的查找工作的话就会同时收集test_01.py
和test_01.py
模块中的用例,如果说此刻我想只执行test_01.py
模块中的用例的话,应该怎么操作呢?因为在pycharm
中在不同的模块中执行的会分开判断,所以说该情况适用于cmd
中
应该输入**pytest -v 目录或者模块
**,该处的模块或者目录值得注意的是,它是相对于rootdir
的路径
按照上例,依旧是求test_01.py
里面的用例
这样就可以得到test_01.py
里面用例的执行情况
pytest
的特色:
1.直接用assert表达式进行断言。并且有详细的报错信息显示
2.自动搜索测试模块和测试函数
3.有非常丰富的库,但是里面的库可能会因为没有维护而在使用的时候出现一些错误
里面的库可以直接通过cmd
或者pycharm
安装
比如说想安装这个插件:
可以直接复制下面的pip…,然后就在cmd
中输入就可以进行安装
在pycharm
软件中也是一样的操作
测试报告有几种格式:1.xml
格式 2.html
格式 3.allure
报告
html
格式使用上面的pytest-html-reporter
插件可以自动生成测试报告
生成报告的步骤
1.在main.py
模块中,之前说到加上参数生成测试报告,那么就将参数填进去就好
生成测试报告:
先使用:
import pytest
pytest.main(["-v","--html-report=reports/my.html"])
其中的--html-report =
是固定的
后面的是相对于rootdir
来说,报告存在的地方,需要注意的是,以此处为例,是存在reports
模块,my.html
里面,但是这个文件不需要提前建,当这段代码执行的时候这个文件会自动创建,测试报告的html
是存放在里面的,再跳转到浏览器就可以查看详细的测试报告了
图中的reports是代码执行后自动生成的,点击my.html
就可以出现
然后就可以得到报告:
切记!!!不能提前建一个叫reports的文件去存放报告,因为他会自动创建!!!不然就会报错!!!!!!!!
allure
报告首先要安装好allure并且正确的配置好环境
下载好allure之后,对其进行解压。找到bin目录,然后复制bin目录的地址,然后打开电脑设置,进行环境配置,点击Path,进行新建,然后把bin目录的地址复制上去就行,这样环境就配置好了。
然后可以再cmd
或者终端下载插件allure-pytest
首先在main.py
文件中输入:
import pytest
pytest.main(["-v","--alluredir=reports"])
其中=
前面的内容是固定的,后面的目录是相对于rootdir
的目录,它和生成html
的一样,不需要提前建一个叫reports
的文件
然后在命令行终端或者cmd
中输入allure serve reports
里面的输入reports
是因为要和前面的等号后面的目录保持一致,这一点很重要
输入完成后按回车键就可以自动进入allure报告的界面
当我们想要多次获得allure报告时,就是指在同一个文件中多次进行测试获得不同的allure报告,有一个前提:先清除前一个获得allure报告文件中的内容。因为如果前一次的还有遗留会对之后生成新的allure报告造成影响,这个时候就需要用到一个指令。比如说都是在reports
目录下进行操作,想要同时进行 清理和执行两个操作:
import pytest
pytest.main(["-v",
"--alluredir=reports",
"--clean-alluredir"])
这样就可以同时把之前的清理掉并执行新的
在allure报告呈现出来的错误中,可以分为两类:
第一种:产品缺陷(product defects):断言失败的情况
第二种:用例缺陷(test defects):用例代码出现错误,根本走不到断言的部分
pytest
的数据驱动使用pytest
数据驱动的特点:1.有一个通用的流程 2.有多组数据要使用
以下是一个利用用户名和密码的多个用例来判断是否登录成功的案例:
def login(user,passw):
if user != 'haha':
return '用户名错误'
if passw != '12345':
return '密码错误'
return '登录成功'
datas = [
{"user":'haha','passw':12345,'checked':'登录成功'},
{"user": 'hehe', 'passw': 12345, 'checked': '用户名错误'},
{"user": 'haha', 'passw': 123456, 'checked': '密码错误'},
{"user": None, 'passw': None, 'checked': '用户名错误'},
]
def test_ddf():
for data in datas:
res = login(data['user'],data['passw'])
assert res == data['checked']
上述代码的基本意思是:先定义了一个login
函数,user
和passw
都是形参,如果用户名和密码都正确就会走到“登录成功”。下面是用变量datas
来存储四组数据,可以看出只有第一组是符合要求的。为了实现这个过程,最后一段代码用了for循环,一条一条的把数据与上面进行对比断言。
乍一看,好像没有什么不对,但是仔细想想,能发现两个问题:
第一个:用for循环,每次进去之后,一直到断言的部分,断言得到一个结果但是这个结果并没有被保存,然后又进行下一个for循环,一直到最后一组数据被用完,因为最后一组数据后面没有内容了,所以整个代码就算有很多组数据最终也只会执行一条用例。
第二个:用for循环的话,只要其中有一组数据执行失败了,那么后面的数据就不会再执行,这样并不能看到每一条数据的执行情况
此处就引出pytest
的数据驱动,它的特点就是:有一个通用的流程并且有多组数据要判断,他很符合上面的情况
使用方法:
import pytest
def login(user,passw):
if user != 'haha':
return '用户名错误'
if passw != '12345':
return '密码错误'
return '登录成功'
datas = [
{"user":'haha','passw':'12345','checked':'登录成功'},
{"user": 'hehe', 'passw': '12345', 'checked': '用户名错误'},
{"user": 'haha', 'passw': '123456', 'checked': '密码错误'},
{"user": None, 'passw': None, 'checked': '用户名错误'},
]
@pytest.mark.parametrize('items',datas)
def test_pytest_ddt(items):
res = login(items['user'],items['passw'])
assert res == items['checked']
首先先导入pytest
login
函数和datas
部分是与前面是一致的,后面的@pytest.mark.parametrize
是固定的,括号里面的items
可以理解为是一个变量,后面的datas
有很多组数据,items
的数据是datas
里面的数据。比如:datas
里面有1,2,3三个数据,那么items
第一次就是1,第二次就是2,第三次就是3
后面的函数部分:函数里面的形参要与括号里面的变量一致,比如这里是items
,那么后面就也要是items
,不然就会报错
使用Pytest
数据驱动最后会分别执行各项数据,并把各项数据当用例去判断
最后得到四条用例的执行结果: