nose探究 一
一 ,安装并查看nose
可以看到是放在了/usr/bin/nosetests
二: 查看这个文件
其实就是个python 脚本
三:分析这个脚本
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
将sys.argv[0]中以-script\.pyw或者.exe结尾的部分去除,例如,假设sys.argv[0]为test-script.pyw,则替换后的sys.argv[0]为test
在命令行中执行 python test.py 输出的是“test.py"
在命令行中执行 python /home/username/.../test.py 输出的是“/home/username/.../test.py"
详解:argv是sys模块下的一个全局变量(也称sys模块的属性),sys.argv是一个list对象,sys.argv的第一个元素是模块名、后面的元素是依次传入的参数!所有元素的类型是str(字符串对象)!
其实重头戏就是run_exit()
re.sub的参数:有五个参数
re.sub(pattern, repl, string, count=0, flags=0)
其中三个必选参数:pattern, repl, string
两个可选参数:count, flags
第一个:pattern
pattern,表示正则中的模式字符串。
反斜杠加数字(\N),则对应着匹配的组(matched group)
比如\6,表示匹配前面pattern中的第6个group
第二个参数:repl
repl,就是replacement,被替换,的字符串的意思。
repl可以是字符串,也可以是函数。
repl是字符串
如果repl是字符串的话,其中的任何反斜杠转义字符,都会被处理的。
即:
\n:会被处理为对应的换行符;
\r:会被处理为回车符;
其他不能识别的转移字符,则只是被识别为普通的字符:
比如\j,会被处理为j这个字母本身;
反斜杠加g以及中括号内一个名字,即:\g,对应着命了名的组,named group
第三个参数:string
string,即表示要被处理,要被替换的那个string字符串。
没什么特殊要说明。
第四个参数:count
举例说明:
继续之前的例子,假如对于匹配到的内容,只处理其中一部分。
比如对于:
hello 123 world 456 nihao 789
1
只是像要处理前面两个数字:123,456,分别给他们加111,而不处理789,
那么就可以写成:
replacedStr = re.sub("(?P\d+)", _add111, inputStr, 2);
四: 看一下 from nose import run_exit
<module 'nose' from '/usr/lib/python2.7/site-packages/nose/__init__.pyc'>
>>> from nose import run_exit
>>> print(run_exit)
<class 'nose.core.TestProgram'>
五:看一下/usr/lib/python2.7/site-packages/nose/__init__.py
map() 会根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
语法
map() 函数语法:
map(function, iterable, ...)
实际上,如果目录中包含了 __init__.py 时,当用 import 导入该目录时,会执行 __init__.py 里面的代码。
而__all__,则可以控制*所表示要引入的东西(模块,函数,类等):
import究竟是如何工作的呢?假设你导入一个模块abc,就像这样:
Python中的绝对导入和相对导入,解决了我很多困惑,区别在这里!
Python要做的第一件事是查找sys.modules中的abc名称。这是预先导入的所有模块的缓存。
如果在模块缓存中没有找到该名称,Python将通过内置模块列表进行搜索。这些模块是和Python一起预先安装的,并且可以在Python标准库中找到。如果在内置模块中仍没有找到该名称,那么Python在sys.path定义的目录列表中搜索它。此列表通常包括当前目录,首先搜索该目录。
当Python找到该模块时,将它绑定到本地作用域中的名称。这意味着现在定义了abc,而且可以在当前文件中使用,而不引发NameError。
如果找不到该名字,会得到ModuleNotFoundError。你可以在Python文档找到更多关于导入的信息!
导入语句的风格
Python的官方风格指南——PEP 8,在编写导入语句时有几个忠告。总结如下:
1. 导入总是位于文件的顶部,在任何模块注释和文档字符串之后。
2. 导入应该根据导入情况来划分。通常有三类:
标准库导入(Python的内置模块)
相关第三方导入(已安装且不属于当前应用程序的模块)
本地应用程序导入(属于当前应用程序的模块)
3. 每一组导入应该被空行隔开。
六:我们来看一下run_exit
[root@alex-vpc-hutong nose]# cat core.py
"""Collect and run tests, returning success or failure.
The arguments to TestProgram() are the same as to
:func:`main()` and :func:`run()`:
* module: All tests are in this module (default: None)
* defaultTest: Tests to load (default: '.')
* argv: Command line arguments (default: None; sys.argv is read)
* testRunner: Test runner instance (default: None)
* testLoader: Test loader instance (default: None)
* env: Environment; ignored if config is provided (default: None;
os.environ is read)
* config: :class:`nose.config.Config` instance (default: None)
* suite: Suite or list of tests to run (default: None). Passing a
suite or lists of tests will bypass all test discovery and
loading. *ALSO NOTE* that if you pass a unittest.TestSuite
instance as the suite, context fixtures at the class, module and
package level will not be used, and many plugin hooks will not
be called. If you want normal nose behavior, either pass a list
of tests, or a fully-configured :class:`nose.suite.ContextSuite`.
* exit: Exit after running tests and printing report (default: True)
* plugins: List of plugins to use; ignored if config is provided
(default: load plugins with DefaultPluginManager)
* addplugins: List of **extra** plugins to use. Pass a list of plugin
instances in this argument to make custom plugins available while
still using the DefaultPluginManager.
"""
"""Collect and run tests, returning success or failure.
The arguments to TestProgram() are the same as to
:func:`main()` and :func:`run()`:
* module: All tests are in this module (default: None)
* defaultTest: Tests to load (default: '.')
* argv: Command line arguments (default: None; sys.argv is read)
* testRunner: Test runner instance (default: None)
* testLoader: Test loader instance (default: None)
* env: Environment; ignored if config is provided (default: None;
os.environ is read)
* config: :class:`nose.config.Config` instance (default: None)
* suite: Suite or list of tests to run (default: None). Passing a
suite or lists of tests will bypass all test discovery and
loading. *ALSO NOTE* that if you pass a unittest.TestSuite
instance as the suite, context fixtures at the class, module and
package level will not be used, and many plugin hooks will not
be called. If you want normal nose behavior, either pass a list
of tests, or a fully-configured :class:`nose.suite.ContextSuite`.
* exit: Exit after running tests and printing report (default: True)
* plugins: List of plugins to use; ignored if config is provided
(default: load plugins with DefaultPluginManager)
* addplugins: List of **extra** plugins to use. Pass a list of plugin
instances in this argument to make custom plugins available while
still using the DefaultPluginManager.
"""
其实就用的是老祖宗unittest
继承了老祖宗,然后修改了老祖宗的方法!
父类:
子类:
学会用folding:
子类最终用了父类的runTests
七,看下runTests