一、模块的导入方式
1、 import方式导入(绝对导入):在后续代码中调用此模块中的类,函数,属性等都是通过:模块名.函数名、模块名.类名、模块名.属性名的方式调用。
import datetime
import time
print("import方式导入:")
print(datetime.datetime.now())
print(time.time())
结果:
import方式导入:
2019-07-09 09:22:58.838245
1562635378.8382452
2、 form...import 方式导入(相对导入):在后续代码中调用此模块中的类,函数,属性等都是通过直接写类名,函数名,属性名。
from datetime import datetime
from time import *
print("form...import方式导入:")
print(datetime.now())
print(time())
结果:
form...import方式导入:
2019-07-09 09:23:23.161034
1562635403.1610339
二、模块的调用
从上例可以知道,在python中能直接调用系统模块,同理,也可以调用自己创建的模块,尤其在自动化测试中,调用执行测试用例时,用得比较多,一般分为同级目录调用和跨目录模块调用。
1、同级目录模块调用
在test_case目录下,创建了test_a.py以及test_b.py文件,它两是同一目录下的文件。
test_a.py文件:
print('this is test_a')
test_b.py文件:
import test_a
print('this is test_b')
执行test_b.py能正常执行
this is test_a
this is test_b
2、跨目录模块调用
在test_case目录下,创建了test_aaa文件夹,并在其下创建了test_a.py以及test_ccc文件夹,在test_ccc文件下创建了test_c.py文件,现在test_a.py和test_c.py它两是不在同一目录下。
test_a.py文件:
import test_c
print('this is test_a')
test_c.py文件:
print('this is test_c')
执行test_a.py文件时,提示错误:不能找到模块
import test_c
ModuleNotFoundError: No module named 'test_c'
在之前同一级目录下,都能运行,不同目录下就出现问题了。这是为什么呢?要理解它,需要知道执行import语句时,到底发生了什么?总结如下:
- 第一步,创建一个新的module对象;
- 第二步,把这个module对象插入到sys.module中;
- 第三步,找到module程序所在位置,转载module的代码。这里需要注意的是程序查找的顺序方法,首先,是找当前路径(以及当前目录指定的sys.path),然后是PythonPATH,再然后是python的安装路径。如果当前路径存在或PythonPATH中存在与标准module同样名称的模块时,则会执行当前路径存在或PythonPATH中存在的模块,所以在给文件名取名称时需要注意;
- 第四步,执行新的module中对应的代码。
了解原理后,就明白了,在引入在不同目录下的模块时,import不能找到执行的模块,那么需要指定相应的路径才能找到并执行。如下:
import sys
sys.path.append(r'E:\python\unittest_test\test_case\test_aaa\test_ccc')
import test_c
print('this is test_a')
结果:已经能找到并执行程序
this is test_c
this is test_a
三、包管理
包的定义:一个包(package)就是放在一个文件夹里的模块集合。包的名字就是文件夹的名字。
现在考虑实际工作中的使用场景,在执行测试用例时,众多的测试用例可能分布在不同目录层级下的文件中,也就是包中国。此时,需要用到python中的dicover函数,它会自动查找到我们想要的测试用例脚本文件,而不用我们手动去加入每个测试用例脚本文件名称。比如:
if __name__ == '__main__':
#构造测试集
suite = unittest.TestSuite()
suite.addTest('test_a')#手动加入每个测试用例脚本文件名称
suite.addTest('test_b')#手动加入每个测试用例脚本文件名称
suite.addTest('test_c')#手动加入每个测试用例脚本文件名称
#执行测试
runner = unittest.TextTestRunner()
runner.run(suite)
当测试用例成百上千时,手动的效率可想而知是如何低下,于是轮到dicover函数出场:
import unittest
unittest.defaultTestLoader.discover(start_dir=,pattern='test*.py',top_level_dir=None)
discover(start_dir=,pattern='test*.py',top_level_dir=None)
- start_dir:要测试的模块名或者测试用例目录;
- pattern:表示用例文件名的匹配原则。比如:pattern='test.py',这里匹配的是test开头的.py类型的文件,星号“”表示任意多个字符;
- top_level_dir:测试模块的顶层目录。如果没有,默认为None。
现在用dicover函数方法去查找不同目录下的测试用例脚本文件,比如:执行test_one.py文件,找到并执行test_a.py、test_b.py和test_c.py文件。
执行test_one.py文件:
import unittest
test_dir = r'E:\python\unittest_test\test_case'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(discover)
结果:没有找到,也没有执行任何的测试用例
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
这是为什么?因为我们在执行程序的时候要告诉python,我们的测试用例放在哪些包中,那怎么告诉python呢?其实很简单,也就是把一个名为__ init__.py的文件(通常是文件内容为空)放在文件夹中。比如:
现在我们再次执行test_one.py文件,看能否找到并执行test_a.py、test_b.py和test_c.py文件。
import unittest
test_dir = r'E:\python\unittest_test\test_case'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(discover)
结果:已经能成功找到!
this is test_a
this is test_c
this is test_b
这里需要注意,unittest框架默认根据ASCII码的顺序加载测试用例,数字与字母的顺序为:09,AZ,a~z。所以你会看到以上的执行结果,因为它查找到的文件夹名称的顺序是先test_aaa,然后是test_bbb。所以先执行test_a.py,再test_c.py,最后test_b.py。
四、使用模块或者引入模块的时候需要注意哪些?
1、使用模块的时候需要注意:
模块名要遵循python的命名规范,也就是尽量使用小写命名,首字母保持小写,尽量不要用下划线(除非多个单词,且数量不多的情况),
不要使用中文或者特殊字符。
模块名不要和系统模块名冲突,最好先检查系统是否已经存在该模块,检查的方法是在python的交互环境中执行import XXX,
若成功,则说明存在此模块。可以通过import导入数据,另外,需要注意变量的作用域。
自己创建模块名称时,要注意命名,不能和python自带的模块名称冲突。
2、引入模块的时候需要注意:
import导入几个模块时,要用逗号进行分开。
模块名字太长可以取别名,比如:import XX as xx等
from import,是从模块名引入方法名