1. 程式人生 > >Testing shell commands from Python

Testing shell commands from Python

   如何測試shell命令?最近,我遇到了一些情況,我想執行shell命令進行測試,Python稱為萬能膠水語言,一些自動化測試都可以完成,目前手頭的工作都是用python完成的.但是無法從Python中找到有關如何進行測試的教程。在google上搜索了很久之後,我找到了一個適合我的解決方案,也許它也適合你!

為什麼使用Python進行測試?

您可以使用專用工具來測試shell命令。為什麼選擇Python而不是其他語言或者工具?但是如果您經常使用Python,那麼使用Python是有意義的,因為Python已經包含了健壯的測試功能,這些功能很容易與其他工具整合。通過測試Python中的shell命令,您可以利用這些工具,並避免跟蹤不同地方的測試。另外,如果您已經熟悉用Python編寫測試,那麼為shell命令編寫測試就變得輕而易舉了。

Use cases

For the Netherlands eScience Center Python package template, I wanted tests to verify that the generated package can be installed, that the tests can be run, and that the documentation can be generated without errors. My Python text processing package nlppln contains 

CWL specifications of text mining tools, that can be validated by running them using a command line tool called cwltool. Another use case would be testing your package’s console scripts(although in this case it might be more convenient to use a package for creating command line interfaces that comes with built-in testing functionality, such as 
Click
).

 

The sh package

You can run shell commands from Python using the subprocess module from the Python standard library. However, using this module is a hassle, because you have to do all the error handling yourself. Sh is a Python package that takes care of all that and allows you to run shell commands using a single line of code. If you want to run python setup.py install, all you have to do is:

import sh
sh.python(['setup.py', 'install'])

If you want to run foo and it is installed on your system, you can just do sh.foo().

Writing a test

So how can we use this for testing? Let’s look at an example. For the Python template, I want to test whether a project generated from the cookiecuttertemplate can be installed without errors. The goal of the template is to help users write high quality code with less effort, and having an installable empty project is a good first step. The code for the test that tests the installation is:

import pytest
import os
import sh
def test_install(cookies):
# generate a temporary project using the cookiecutter
# cookies fixture
project = cookies.bake()
  # remember the directory where tests should be run from
cwd = os.getcwd()
# change directories to the generated project directory
# (the installation command must be run from here)
os.chdir(str(project.project))
  try:
# run the shell command
sh.python(['setup.py', 'install'])
except sh.ErrorReturnCode as e:
# print the error, so we know what went wrong
print(e)
# make sure the test fails
pytest.fail(e)
finally:
# always change directories to the test directory
os.chdir(cwd)

That is all there is to it!

More examples

Of course there is a lot more you can do, e.g., checking whether files existafter running a shell command, or verifying the contents of generated files. What use cases can you come up with?

On Windows: use subprocess

Sh does not work on Windows. If you need to test shell commands on Windows, you are stuck with subprocess. Provenance tracking package recipycontains some nice examples of tests using subprocess that might help you on your way.