如何在没有 AttributeError 的情况下在 GitLab CI 管道中使用变量?
How to use Variables in GitLab CI pipeline without AttributeError?
我正在使用一个变量来定义我的 .gitlab-ci.yml
中的 ROOT_DIR
variables:
ROOT_DIR: "/builds/company/projects/projectname/"
在我调用 test.py 函数的作业中:
ut-job:
stage: test
script:
- echo "Unit testing ..."
- python3 tests/test_file.py "$ROOT_DIR"
在test_file.py中我调用命令行inout如下:
if __name__ == "__main__":
if sys.platform == "Darwin" or sys.platform == "Windows":
load_dotenv()
ROOT_DIR = os.getenv("ROOT_DIR")
else:
ROOT_DIR=sys.argv[1]
print("PLatform: " + sys.platform)
print("ROOT_DIR: " + ROOT_DIR)
unittest.main()
管道输出中的打印语句正确打印了 ROOT_DIR,因此 sys.argv 正确获取了变量。
但是,管道失败
AttributeError: module '__main__' has no attribute '/builds/company/projects/projectname/'
意思是,test_file.py main 获取变量但不知何故试图将其也用作属性。
有人可以提示我做错了什么吗?谢谢
调用test_file.py
时无需传递参数。我认为这是导致错误的原因。
ut-job:
stage: test
script:
- echo "Unit testing ..."
- python3 tests/test_file.py
这里的问题是,当您调用 unittest.main
时,它会检查 sys.argv
的内容以获取参数,在本例中为测试名称。它将尝试使用提供的参数通过在当前模块上使用 getattr 来获取 运行 的测试。在这种情况下,导致属性错误。
例如,假设您有一个这样的测试文件 (t.py
):
import unittest
class Foo(unittest.TestCase):
def test_foo(self):
...
class Bar(unittest.TestCase):
def test_bar(self):
...
unittest.main()
观察向该文件添加参数时的不同结果:
没有参数 2 个测试 运行:
$ python3 ./t.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
使用参数Foo
只有一个测试(Foo
)运行s:
$ python3 ./t.py Foo
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
如果您提供一个不存在的测试参数(例如,Baz
),您将收到参数传递的属性错误:
$ python3 ./t.py Baz
E
======================================================================
ERROR: Baz (unittest.loader._FailedTest)
----------------------------------------------------------------------
AttributeError: module '__main__' has no attribute 'Baz'
----------------------------------------------------------------------
Ran 1 test in 0.000s
要解决此问题,您可以 (1) 不为脚本传递任何参数或 (2) 在调用 unittest.main
之前修改 sys.argv
if __name__ == "__main__":
if sys.platform == "Darwin" or sys.platform == "Windows":
load_dotenv()
ROOT_DIR = os.getenv("ROOT_DIR")
else:
ROOT_DIR=sys.argv[1]
sys.argv.pop(1) # remove rootdir from cli arguments
print("PLatform: " + sys.platform)
print("ROOT_DIR: " + ROOT_DIR)
unittest.main()
我正在使用一个变量来定义我的 .gitlab-ci.yml
中的 ROOT_DIRvariables:
ROOT_DIR: "/builds/company/projects/projectname/"
在我调用 test.py 函数的作业中:
ut-job:
stage: test
script:
- echo "Unit testing ..."
- python3 tests/test_file.py "$ROOT_DIR"
在test_file.py中我调用命令行inout如下:
if __name__ == "__main__":
if sys.platform == "Darwin" or sys.platform == "Windows":
load_dotenv()
ROOT_DIR = os.getenv("ROOT_DIR")
else:
ROOT_DIR=sys.argv[1]
print("PLatform: " + sys.platform)
print("ROOT_DIR: " + ROOT_DIR)
unittest.main()
管道输出中的打印语句正确打印了 ROOT_DIR,因此 sys.argv 正确获取了变量。
但是,管道失败
AttributeError: module '__main__' has no attribute '/builds/company/projects/projectname/'
意思是,test_file.py main 获取变量但不知何故试图将其也用作属性。
有人可以提示我做错了什么吗?谢谢
调用test_file.py
时无需传递参数。我认为这是导致错误的原因。
ut-job:
stage: test
script:
- echo "Unit testing ..."
- python3 tests/test_file.py
这里的问题是,当您调用 unittest.main
时,它会检查 sys.argv
的内容以获取参数,在本例中为测试名称。它将尝试使用提供的参数通过在当前模块上使用 getattr 来获取 运行 的测试。在这种情况下,导致属性错误。
例如,假设您有一个这样的测试文件 (t.py
):
import unittest
class Foo(unittest.TestCase):
def test_foo(self):
...
class Bar(unittest.TestCase):
def test_bar(self):
...
unittest.main()
观察向该文件添加参数时的不同结果:
没有参数 2 个测试 运行:
$ python3 ./t.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
使用参数Foo
只有一个测试(Foo
)运行s:
$ python3 ./t.py Foo
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
如果您提供一个不存在的测试参数(例如,Baz
),您将收到参数传递的属性错误:
$ python3 ./t.py Baz
E
======================================================================
ERROR: Baz (unittest.loader._FailedTest)
----------------------------------------------------------------------
AttributeError: module '__main__' has no attribute 'Baz'
----------------------------------------------------------------------
Ran 1 test in 0.000s
要解决此问题,您可以 (1) 不为脚本传递任何参数或 (2) 在调用 unittest.main
sys.argv
if __name__ == "__main__":
if sys.platform == "Darwin" or sys.platform == "Windows":
load_dotenv()
ROOT_DIR = os.getenv("ROOT_DIR")
else:
ROOT_DIR=sys.argv[1]
sys.argv.pop(1) # remove rootdir from cli arguments
print("PLatform: " + sys.platform)
print("ROOT_DIR: " + ROOT_DIR)
unittest.main()