我有一个Shell脚本,当前需要3个args。我通过具有外壳程序脚本文件名,要在其上运行python脚本的目录的外壳程序脚本以及测试数据目录的名称来运行此脚本。我希望能够编写一个执行以下命令的单元测试,但是仅当我要更改日期时(取决于可用数据,它会通过还是失败)。
main_config.sh
yamldir=$1
for yaml in $(ls ${yamldir}/*.yaml | grep -v "export_config.yaml"); do
if [ "$yaml" != "export_config.yaml" ]; then
echo "Running export for $yaml file...";
python valid.py -p ${yamldir}/export_config.yaml -e $yaml -d ${endDate}
wait
fi
done
这是在命令行上执行的
./main_config.sh /Users/name/Desktop/yaml/ 2018-12-23
这将失败并在终端上输出,因为没有名为2012-12-23的目录:
./main_config.sh /yaml/ 2018-12-23
Running export for apa.yaml file...
apa.json does not exist
如果目录存在,它将通过并在终端上输出:
Running export for apa.yaml file...
File Name: apa.json Exists
File Size: 234 Bytes
Writing to file
我的python脚本脚本如下:
def main(get_config):
cfg = get_config()[0] # export_config.yaml
data = get_config()[1] # export_apa.yaml
date = get_config()[2] # data folder - YYYY-MM-DD
# Conditional Logic
def get_config():
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--parameter-file", action="store", required=True)
parser.add_argument("-e", "--export-data-file", action="store", required=True)
parser.add_argument("-d", "--export-date", action="store", required=False)
args = parser.parse_args()
return [funcs.read_config(args.parameter_file), funcs.read_config(args.export_data_file), args.export_date]
if __name__ == "__main__":
logging.getLogger().setLevel(logging.INFO)
main(get_config)
答案 0 :(得分:0)
在我看来,这似乎不是典型的单元测试(测试功能或方法),而是集成测试(从外部测试子系统)。但是当然,您仍然可以使用unittest
之类的典型Python测试工具来解决此问题。
一个简单的解决方案是使用subprocess
运行脚本,捕获输出,然后将其解析为测试的一部分:
import unittest
import os
import sys
if os.name == 'posix' and sys.version_info[0] < 3:
import subprocess32 as subprocess
else:
import subprocess
class TestScriptInvocation(unittest.TestCase):
def setUp(self):
"""call the script and record its output"""
result = subprocess.run(["./main_config.sh", "/Users/yasserkhan/Desktop/yaml/", "2018-12-23"], stdout=subprocess.PIPE)
self.returncode = result.returncode
self.output_lines = result.stdout.decode('utf-8').split('\n')
def test_returncode(self):
self.assertEqual(self.returncode, 0)
def test_last_line_indicates_success(self):
self.assertEqual(self.output_lines[-1], 'Writing to file')
if __name__ == '__main__':
unittest.main()
请注意,此代码使用Python 3 subprocess
模块的反向端口。另外,它尝试解码result.stdout
的内容,因为在Python 3上它是bytes
对象,而不是在Python 2上是str
。我没有测试它,但是这些两件事应该使代码在2到3之间可移植。
还请注意,使用诸如"/Users/yasserkhan/Desktop/yaml"
之类的绝对路径可能会轻易中断,因此您将需要查找相对路径或使用环境变量将基本路径传递给测试。
您可以添加其他测试,以分析其他行并检查合理的输出,例如文件大小在预期范围内。