测试需求:我们有一些具体的指令需要我们使用pytest自动去执行,查看指令是否能够执行成功,不用我们手动去一个个输入指令,这样更快捷一点
话不多说,我们就开始完成指令是如何测试的
1.首先我们要知道,我们测试的指令都是在固定的目录下去执行的,所以第一步,我们需要拿到我们执行测试指令的位置,因为我们可能多个指令都会在该位置执行,所以我们可以将切换目录的方法封装起来,放在pytest的夹具中,这样我们多个指令测试都可以使用该方法,封装如下
import os
import pytest
# pytest.fixture这个表示这个函数是一个夹具函数
@pytest.fixture
def switchover_path():
path = '要执行指令的目录'
# now_dir_path是我们现在所处的目录路径
now_dir_path = os.getcwd()
# 下面这句话表示切换到我们的path路径
os.chdir(path)
# 在夹具函数中碰到yield,会直接切换到我们的测试函数执行,当我们的测试函数结束才会执行yield下面的逻辑
yield
# 当测试函数执行完毕之后就会执行下面这句话,会再次切换到我们原来的目录中
os.chdir(now_dir_path)
2.当我们切换到执行命令的目录之后,下面就需要拼接我们想要执行的命令,比如我们想在linux系统中,某个目录下执行ls这个命令,那我们就可以直接写一个命令函数
def test_run_ls(switchover_path):
# 这句话表示我们的命令为ls
run_ls = 'ls'
在这个方法中,我们定义了一个指令,看上去是我们直接定义了一个函数,但是在执行过程中不是直接执行改函数,实际在测试用例执行过程中,我们使用到了夹具中的方法,这个方法会类似于装饰器一样,首先执行该方法,所以当我们在定义run_ls之前其实我们已经通过夹具中的方法切换到了执行命令的目录,因此,我们只要执行这个方法就可以了
3.通过前两步,我们切换到了执行指令的目录以及定义了一个指令,下面需要做的就是我们来执行这个指令,这个时候我们就需要用到一个模块subprocess模块,该模块的getstatusoutput方法可以执行指定的命令,并返回其执行结果和输出。具体而言,subprocess.getstatusoutput('命令')
会在当前系统上执行给定的命令 cmd
,然后将命令的输出作为字符串返回,并返回一个二元组 (status, output)
。其中,status
是命令的退出状态码(0 表示成功,非零值表示失败),output
是命令的输出结果。
import subprocess
cmd = "ls -l"
status, output = subprocess.getstatusoutput(cmd)
if status == 0:
print("命令执行成功!")
print("输出:\n", output)
else:
print("命令执行失败!")
print("错误信息:\n", output)
我们可以查看一下该方法的源码
def getstatusoutput(cmd):
"""Return (exitcode, output) of executing cmd in a shell.
Execute the string 'cmd' in a shell with 'check_output' and
return a 2-tuple (status, output). The locale encoding is used
to decode the output and process newlines.
A trailing newline is stripped from the output.
The exit status for the command can be interpreted
according to the rules for the function 'wait'. Example:
try:
data = check_output(cmd, shell=True, text=True, stderr=STDOUT)
exitcode = 0
except CalledProcessError as ex:
data = ex.output
exitcode = ex.returncode
if data[-1:] == '\n':
data = data[:-1]
return exitcode, data
# 源码中明确告诉我们Return返回一个元组包含了(exitcode, output) ,一个状态,另一个是shell的输出结果
所以我们再次封装一个函数,专门用来执行我们的cmd命令,如下所示
def run_cmd(cmd):
# 在这个方法中将cmd执行结果返回出去,那我们再次完善我们的测试用例
return subprocess.getstatusoutput(cmd)
完善后的测试用例
def test_run_ls(switchover_path):
# 这句话表示我们的命令为ls
run_ls = 'ls'
# 这里我们调用了命令的执行方法,拿到返回结果
status, output = run_cmd(run_ls)
# 如果返回状态是0就证明我们这条指令是执行成功的
assert status == 0
这样我们就简单的达到了我们对用命令行的测试,对于更丰富的命令行测试,我们在这个基础上面拓展就可以
上次我们做了一个简单的命令行测试,我们可以使用pytest做命令行的测试,拿到命令行的返回结果以及命令是否执行成功,但是忽略了一个比较大的问题,我们使用subprocess.getstatusoutput('命令')这个执行我们的命令只能在我当前的linux系统中执行,最近我想做win系统下兼容能够双系统做命令行测试的时候,就行不太通了,因为我想要在windows的powershell中执行命令行,所以我需要在进行兼容性扩展,下面是扩展后的函数
import sys
def run_cmd(cmd):
if sys.platform == "linux":
# 我们在linux系统中使用这个函数返回命令执行状态和结果
return subprocess.getstatusoutput(cmd)
# 当我们是windows系统中就需要换一个了
elif sys,platform == "win32":
# 我们要拼接一个cd命令,这样直接cd到指定的路径下执行命令
command_line = 'cd {0}; '.format(get_path_sdk) + cmd
# 在win系统上面我们使用run函数,配置执行的powershell.exe
result = subprocess.run(['powershell.exe', '-Command', command_line], capture_output=True, text=True)
# win下面他只有一个返回值,里面包含了响应状态码和输出内容,所以我们把这两个值分别拿出来,这样返回结果就跟linux系统下一致,就不需要再去我们测试例子中进行修改
return result.returncode, result.stdout
当然这个是我们对执行命令行进行了系统的区别,sys模块可以让我们拿到当前执行代码的操作系统
关于pytest的debug使用
之前写测试用例,一直没有办法进行debug调试,每次写错了可能要排查好久,后来发现我们使用pytest是可以执行run命令的就是需要配置不一样,大概一下步骤就可以配置了
1.在 PyCharm 的顶部菜单中选择 "Run" > "Edit Configurations..."。
2.在弹出的窗口中,点击左上角的加号图标,选择 "Python tests" > "pytest"
3.在右侧的 "Name" 字段中,为配置添加一个名称,比如 "Pytest"。
4.在 "Target" 字段中,选择测试文件或目录。您可以单击右侧的 "..." 按钮,然后选择测试文件或目录
5.在 "Additional arguments" 字段中,输入您想要传递给 pytest 的额外命令行参数
6.确保 "Python interpreter" 字段中选择了正确的 Python 解释器。
7.点击 "OK" 保存配置
这样就配置好了run命令,可以直接点run就启动项目,这个配置好以后我们就可以使用我们debug模式了,打开debug,打上断点就可以愉快的看到我们的代码是怎么样在走了,这个时候要注意一点,就是我们的pytest是从上到下挨着加载测试文件,再从文件里面从上到下加载测试用例,所以如果我们debug调试的函数是在第二个测试文件里面,那么必须等第一个测试文件全部执行完毕以后才能加载,这个时候我们可以使用pytest的忽略装饰器,@pytest.mark.skip(),将我们需要debug函数之前的测试例子全部忽略掉就可以快速debug调试