我必须维护一个大约 3500
行的批处理脚本,其中散布着 GOTO
。看来原来的“开发者”没有听说过this famous paper 和模块化编程。
脚本的作用是什么?
该脚本使用不同的选项处理多个程序的(静默)安装/卸载/重新安装。它可以分为几个文件,分别处理每个程序的一部分。问题是,如果您尝试参与另一个文件的一部分,该部分仍然会GOTO
需要位于原始脚本中的另一个部分。
重构?
通常情况下,如果没有自动化测试,您不会进行重构(这样您就可以确定没有破坏任何内容),但我不知道该怎么做。没有相应的测试框架。
部分解决方案
我提出了一个部分“解决方案”,它是对 characterization tests 的某种改编。 (来自Working Effectively with Legacy Code by Michael Feathers)和approval tests :
- 创建另一个脚本:test.py
,用 echo 替换所有命令(如 copy 或 msiexec),
- 将输出重定向到文本文件 (good.txt
),
- 更改原来的批处理脚本,
- 再次运行 test.py
脚本并将输出保存到另一个文本文件 (current.txt
),
- diff good.txt
和 current.txt
-> 如果没有差异,那么我没有破坏任何东西,但如果它们不同,我需要检查我是否破坏了东西。
部分解决方案的问题
如何捕获并替换所有命令?我可以列出要替换的命令列表,但也有很多字符串连接来获取要安装的程序的名称和路径。
CMD 级别捕获/ Hook ?
有什么方法可以连接到命令行解释器 (CMD.exe
),以便我可以用 echo
即时替换对安装程序的所有调用?
其他建议?
我处理问题的方式是否错误?我能以某种方式做得更好吗?你有什么我可以使用的建议吗?
最佳答案
您可以将所有 COPY
、DEL
或 CALL
替换为 %COPY%
、%DEL %
,...
因此您可以使用相同的文件进行生产和测试。
@echo off
if not defined UNITTEST (
set "COPY=COPY"
set "DEL=DEL"
set "CALL=CALL"
)
%COPY% src dest
%DEL% somefile.txt
%CALL% installer.exe
从你的unittest.bat中,你可以通过以下方式启动它
@echo off
set "COPY=>>trace.log ECHO COPY"
set "DEL=>>trace.log ECHO DEL"
set "CALL=>>trace.log CALL ECHO "
del trace.log
set "unittest=Active"
call production.bat
fc good.txt trace.log
关于batch-file - 如何重构充满 GOTO 的 Windows 批处理脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22208154/