geekdoc-python-zh/docs/pythonlibrary/how-to-run-python-tests-con...

5.7 KiB
Raw Permalink Blame History

如何在编码时“连续”运行 Python 测试

原文:https://www.blog.pythonlibrary.org/2017/03/14/how-to-run-python-tests-continuously-while-coding/

上周,我做了一些测试驱动开发培训,无意中听到有人提到另一种编程语言,它有一个测试运行程序,你可以设置它来监视你的项目目录,并在文件改变时运行你的测试。我认为这是个好主意。我还认为我可以轻松地编写自己的 Python 脚本来做同样的事情。这是一个相当粗略的版本:


import argparse
import os
import subprocess
import time

def get_args():
    parser = argparse.ArgumentParser(
        description="A File Watcher that executes the specified tests"
        )
    parser.add_argument('--tests', action='store', required=True,
                        help='The path to the test file to run')
    parser.add_argument('--project', action='store', required=False,
                        help='The folder where the project files are')
    return parser.parse_args()

def watcher(test_path, project_path=None):
    if not project_path:
        project_path = os.path.dirname(test_path)

    f_dict = {}

    while True:
        files = os.listdir(project_path)
        for f in files:
            full_path = os.path.join(project_path, f)
            mod_time = os.stat(full_path).st_mtime
            if full_path not in f_dict:
                f_dict[full_path] = mod_time
            elif mod_time != f_dict[full_path]:
                # Run the tests
                cmd = ['python', test_path]
                subprocess.call(cmd)
                print('-' * 70)
                f_dict[full_path] = mod_time

        time.sleep(1)

def main():
    args = get_args()
    w = watcher(args.tests, args.project)

if __name__ == '__main__':
    main()

要运行这个脚本,您需要执行如下操作:


python watcher.py --test ~/path/to/tests.py --project ~/project/path

现在让我们花点时间来谈谈这个脚本。第一个函数使用 Python 的 argparse 模块让程序接受最多两个命令行参数:- test 和- project。第一个是 Python 测试脚本的路径,第二个是要测试的代码所在的文件夹。下一个函数, watcher ,将永远循环下去,从传入的文件夹中抓取所有文件,或者使用测试文件所在的文件夹。它将获取每个文件的修改时间,并将其保存到字典中。密钥设置为文件的完整路径,值为修改时间。接下来,我们检查修改时间是否已经更改。如果没有,我们睡一会儿,再检查一遍。如果它改变了,我们就运行测试。

此时,您应该能够在您最喜欢的 Python 编辑器中编辑您的代码和测试,并在终端中观察您的测试运行。


使用看门狗

我四处寻找其他跨平台的监视目录的方法,发现了 看门狗 项目。自 2015 年(撰写本文时)以来,它一直没有更新,但我测试了一下,似乎对我来说效果不错。您可以使用 pip 安装看门狗:


pip install watchdog

现在我们已经安装了 watchdog让我们创建一些代码来执行类似于上一个示例的操作:


import argparse
import os
import subprocess
import time

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

def get_args():
    parser = argparse.ArgumentParser(
        description="A File Watcher that executes the specified tests"
        )
    parser.add_argument('--tests', action="store", required=True,
                        help='The path to the test file to run')
    parser.add_argument('--project', action='store', required=False,
                        help='The folder where the project files are')
    return parser.parse_args()

class FW(FileSystemEventHandler):
    def __init__(self, test_file_path):
        self.test_file_path = test_file_path

    def on_any_event(self, event):

        if os.path.exists(self.test_file_path):
            cmd = ['python', self.test_file_path]
            subprocess.call(cmd)
            print('-' * 70)

if __name__ =='__main__':
    args = get_args()
    observer = Observer()
    path = args.tests
    watcher = FW(path)

    if not args.project:
        project_path = os.path.dirname(args.tests)
    else:
        project_path = args.project

    if os.path.exists(path) and os.path.isfile(path):
        observer.schedule(watcher, project_path, recursive=True)
        observer.start()
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            observer.stop()
        observer.join()
    else:
        print('There is something wrong with your test path')

在这段代码中,我们保留了我们的 get_args() 函数并添加了一个类。class 子类的看门狗的 FileSystemEventHandler 类。我们最终将测试文件路径传递给该类,并覆盖了 on_any_event() 方法。此方法在文件系统事件发生时触发。当那发生时,我们运行我们的测试。最后一点在代码的末尾,我们创建了一个 Observer() 对象,告诉它监视指定的项目路径,并在文件发生任何变化时调用我们的事件处理程序。


包扎

此时,您应该能够在自己的代码中尝试这些想法了。也有一些特定于平台的方法来监视一个文件夹(比如 PyWin32 ),但是如果你像我一样在多个操作系统上运行,那么 watchdog 或者 rolling your own 可能是更好的选择。

相关阅读

  • 如何使用 Python 来观察文件的变化?
  • 观察目录的变化