[英]How to ignore certain scripts while testing flask app using pytest in gitlab CI/CD pipeline?
I have a flask-restx
folder with the following structure我有一个具有以下结构的flask-restx
文件夹
.
├── app
│ ├── extensions.py
│ ├── __init__.py
│ └── pv_dimensioning
│ ├── controller.py
│ ├── __init__.py
│ ├── models
│ │ ├── dto.py
│ │ ├── __init__.py
│ │ ├── input_output_model.py
│ │ └── vendor_models.py
│ ├── services
│ │ ├── calculator.py
│ │ ├── database.py
│ │ ├── db_crud.py
│ │ ├── db_input_output.py
│ │ ├── __init__.py
│ │ └── processor.py
│ └── utils
│ ├── decode_verify_jwt.py
│ ├── decorator.py
│ └── __init__.py
├── config.py
├── main.py
├── package.json
├── package-lock.json
├── Pipfile
├── Pipfile.lock
├── README.md
├── serverless.yml
└── tests
└── test_processor.py
The app is connected to a database, that's why there are many scripts in the app that require VPN connection.该应用程序连接到数据库,这就是为什么应用程序中有许多脚本需要 VPN 连接。
I am writing tests using pytest
which I will then run on the gitlab CI/CD
to get a proper coverage
.我正在使用pytest
编写测试,然后我将在gitlab CI/CD
上运行以获得适当的coverage
。 I would like to avoid or omit scripts that can only run when VPN is connected and write tests only for scripts that don't require VPN.我想避免或省略只能在连接 VPN 时运行的脚本,并且只为不需要 VPN 的脚本编写测试。 (I have tests for the scripts that require VPN, but I just don't want to run them in the CI/CD pipeline) (我对需要 VPN 的脚本进行了测试,但我只是不想在 CI/CD 管道中运行它们)
The only script that doesn't require VPN is the processor.py
and the test for that is in test_processor.py
.唯一不需要 VPN 的脚本是processor.py
,测试在test_processor.py
中。
The scripts that I would like to avoid are in the .coveragerc
:我想避免的脚本在.coveragerc
中:
[run]
omit =
*/site-packages/*
*/distutils/*
tests/*
/usr/*
app/__init__.py
app/extensions.py
app/pv_dimensioning/models/*
app/pv_dimensioning/utils/*
app/pv_dimensioning/controller.py
app/pv_dimensioning/services/calculator.py
app/pv_dimensioning/services/database.py
app/pv_dimensioning/services/db_crud.py
app/pv_dimensioning/services/db_input_output.py
[html]
directory = htmlcov
the coverage part of .gitlab-ci.yml
.gitlab-ci.yml
的覆盖部分
stages:
- coverage
coverage:
image: python:3.7
stage: coverage
artifacts:
paths:
- htmlcov/
before_script:
- apt-get -y update
- apt-get install curl
- pip install pipenv
- pipenv install --dev
script:
- pipenv run python -m coverage run -m pytest
- pipenv run python -m coverage report -m
- pipenv run python -m coverage html
after_script:
- pipenv run bash <(curl -s https://codecov.io/bash)
When I run the test in the pipeline, I get the following error:当我在管道中运行测试时,出现以下错误:
$ pipenv run python -m coverage run -m pytest
============================= test session starts ==============================
platform linux -- Python 3.7.10, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
rootdir: /builds/EC/tool/dt-service
plugins: cov-2.11.0
collected 0 items / 1 error
==================================== ERRORS ====================================
___________________ ERROR collecting tests/test_processor.py ___________________
/usr/local/lib/python3.7/urllib/request.py:1350: in do_open
encode_chunked=req.has_header('Transfer-encoding'))
/usr/local/lib/python3.7/http/client.py:1277: in request
self._send_request(method, url, body, headers, encode_chunked)
/usr/local/lib/python3.7/http/client.py:1323: in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
/usr/local/lib/python3.7/http/client.py:1272: in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
/usr/local/lib/python3.7/http/client.py:1032: in _send_output
self.send(msg)
/usr/local/lib/python3.7/http/client.py:972: in send
self.connect()
/usr/local/lib/python3.7/http/client.py:1439: in connect
super().connect()
/usr/local/lib/python3.7/http/client.py:944: in connect
(self.host,self.port), self.timeout, self.source_address)
/usr/local/lib/python3.7/socket.py:707: in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
/usr/local/lib/python3.7/socket.py:752: in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
E socket.gaierror: [Errno -2] Name or service not known
During handling of the above exception, another exception occurred:
tests/test_processor.py:2: in <module>
from app.pv_dimensioning.services.processor import PreProcessings
app/pv_dimensioning/__init__.py:4: in <module>
from .controller import admin_crud_ns as admin_crud_namespace
app/pv_dimensioning/controller.py:5: in <module>
from .services.calculator import DimensionCalculator
app/pv_dimensioning/services/calculator.py:3: in <module>
from .database import DatabaseService
app/pv_dimensioning/services/database.py:6: in <module>
from ..utils.decode_verify_jwt import verifier
app/pv_dimensioning/utils/decode_verify_jwt.py:12: in <module>
with urllib.request.urlopen(keys_url) as f:
/usr/local/lib/python3.7/urllib/request.py:222: in urlopen
return opener.open(url, data, timeout)
/usr/local/lib/python3.7/urllib/request.py:525: in open
response = self._open(req, data)
/usr/local/lib/python3.7/urllib/request.py:543: in _open
'_open', req)
/usr/local/lib/python3.7/urllib/request.py:503: in _call_chain
result = func(*args)
/usr/local/lib/python3.7/urllib/request.py:1393: in https_open
context=self._context, check_hostname=self._check_hostname)
/usr/local/lib/python3.7/urllib/request.py:1352: in do_open
raise URLError(err)
E urllib.error.URLError: <urlopen error [Errno -2] Name or service not known>
=========================== short test summary info ============================
ERROR tests/test_processor.py - urllib.error.URLError: <urlopen error [Errno ...
!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
=============================== 1 error in 1.62s ===============================
In the trace, it can be seen that the scripts that I am trying to ignore aren't being ignored.在跟踪中,可以看出我试图忽略的脚本没有被忽略。 What is the mistake I am doing?我在做什么错误?
As I understand it, coverage is about reporting how much of your codebase is tested, not which tests to run.据我了解,覆盖率是关于报告测试了多少代码库,而不是要运行哪些测试。 What you're doing is excluding things from a report, not stopping the data for the report being created.您正在做的是从报告中排除事物,而不是停止正在创建的报告的数据。
What you should do is skip tests if you know they're going to fail (due to external configuration).如果您知道测试将失败(由于外部配置),您应该做的是跳过测试。 Fortunately pytest provides for this with the skipif
decorator.幸运的是 pytest 使用skipif
装饰器提供了这一点。
I would create a function in tests/conftest.py
which skips tests if the VPN is active.我会在tests/conftest.py
中创建一个 function,如果 VPN 处于活动状态,它会跳过测试。 Something like:就像是:
import socket
import pytest
def _requires_vpn():
has_vpn = False
try:
socket.gethostbyname("<some address only accessible in the VPN>")
has_vpn = True
except socket.error:
pass
return pytest.mark.skipif(not has_vpn, reason="access to the vpn is required")
requires_vpn = _requires_vpn() # this is like the minversion example on the link
Then you can ignore entire test files adding this at the top:然后你可以忽略整个测试文件在顶部添加这个:
pytestmark = requires_vpn
And you can skip specific tests by decorating with this.你可以用这个装饰来跳过特定的测试。
@requires_vpn
def test_this_will_be_skipped():
pass
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.