简体   繁体   中英

How to use Variables in GitLab CI pipeline without AttributeError?

I am using a variable to define the ROOT_DIR in my .gitlab-ci.yml

variables:
  ROOT_DIR: "/builds/company/projects/projectname/"

in the job I call the test.py function:

ut-job:
  stage: test
  script:
    - echo "Unit testing ..."
    - python3 tests/test_file.py "$ROOT_DIR"

In the test_file.py I call the command line inout as follows:

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()

The printstatement in the pipeline output correctly prints the ROOT_DIR, so the sys.argv gets the variable correctly.

However, the pipeline fails with

AttributeError: module '__main__' has no attribute '/builds/company/projects/projectname/'

Meaning, the test_file.py main gets the Variable but somehow tries to use it also as an attribute.

Can somebody hint me what I did wrong?

The issue here is that when you call unittest.main , it inspects the contents of sys.argv for parameters, in this case, test names. It will try to use provided arguments to get tests to run by using getattr on the current module. In this case, resulting in an attribute error.

For example, suppose you have a test file ( t.py ) like this:

import unittest

class Foo(unittest.TestCase):
    def test_foo(self):
        ...

class Bar(unittest.TestCase):
    def test_bar(self):
        ...

unittest.main()

Observe the different results when adding arguments to this file:

With no arguments 2 tests run:

$ python3 ./t.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

With the argument Foo only one test ( Foo ) runs:

$ python3 ./t.py Foo
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

If you provide an argument of a nonexistent test (say, Baz ) you'll get an attribute error for the argument passed:

$ python3 ./t.py Baz
E
======================================================================
ERROR: Baz (unittest.loader._FailedTest)
----------------------------------------------------------------------
AttributeError: module '__main__' has no attribute 'Baz'

----------------------------------------------------------------------
Ran 1 test in 0.000s

To resolve this you can either (1) not pass any arguments for your script or (2) modify sys.argv before calling unittest.main

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()

No need to pass an argument when calling the test_file.py . I believe that is causing the error.

ut-job:
  stage: test
  script:
    - echo "Unit testing ..."
    - python3 tests/test_file.py

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM