Write new style integration tests
The earlier approach for integration tests was unreliable as it used pickled objects from virtualenvs, which didn't work with all the pip internal code and would often require tests to be fixed. In this new approach, a combination of bash and python scripts drive the tests. Test virtualenvs are setup on demand with support for varying python and pip versions. As a result, the test environment (python 3.6) can be completely different from the test environment ie. the env in which pipdeptree is tested. TODO: Get the new approach working with travis and remove old integration tests.
This commit is contained in:
parent
e7da6b3b50
commit
ec1ee96963
|
@ -0,0 +1,4 @@
|
|||
pytest
|
||||
jinja2
|
||||
ipython
|
||||
flake8
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
PROFILE=$1
|
||||
PYTHON_EXE=${PYTHON_EXE:-python3.6}
|
||||
PIP_VERSION=latest
|
||||
|
||||
cd profiles/$PROFILE
|
||||
|
||||
echo "Profile dir: $(pwd)"
|
||||
|
||||
env_dir=".env_$(basename $PYTHON_EXE)_pip-${PIP_VERSION}"
|
||||
|
||||
echo "Profile env: $env_dir"
|
||||
|
||||
if [ ! -d $env_dir ]; then
|
||||
virtualenv -p $PYTHON_EXE $env_dir
|
||||
fi
|
||||
|
||||
pip=$env_dir/bin/pip
|
||||
|
||||
if [ "$PIP_VERSION" == "latest" ]; then
|
||||
$pip install -U pip
|
||||
fi
|
||||
|
||||
# Install requirements
|
||||
$pip install -r requirements.txt
|
||||
|
||||
# Install pipdeptree
|
||||
$pip install -e ../../../
|
||||
|
||||
pip_deptree=$env_dir/bin/pipdeptree
|
||||
|
||||
export TEST_PROFILE_DIR="profiles/$PROFILE"
|
||||
export PIPDEPTREE_EXE=$TEST_PROFILE_DIR/$pip_deptree
|
||||
|
||||
cd -
|
||||
|
||||
py.test e2e_tests.py
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
import json
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
from jinja2 import Environment, BaseLoader
|
||||
import pytest
|
||||
|
||||
|
||||
## Uncomment following lines for running in shell
|
||||
# os.environ['TEST_PROFILE_DIR'] = 'profiles/webapp'
|
||||
# os.environ['PIPDEPTREE_EXE'] = 'profiles/webapp/.env_python3.6_pip-latest/bin/pipdeptree'
|
||||
|
||||
|
||||
test_profile_dir = os.environ['TEST_PROFILE_DIR']
|
||||
pipdeptree_path = os.environ['PIPDEPTREE_EXE']
|
||||
|
||||
|
||||
def load_test_spec():
|
||||
test_spec_path = os.path.join(test_profile_dir, 'test_spec.json')
|
||||
with open(test_spec_path) as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
test_spec = load_test_spec()
|
||||
|
||||
|
||||
def final_command(s):
|
||||
tmpl = Environment(loader=BaseLoader).from_string(s)
|
||||
return tmpl.render(pipdeptree=pipdeptree_path)
|
||||
|
||||
|
||||
def _test_cmp_with_file_contents(spec):
|
||||
p = subprocess.Popen(shlex.split(spec['command']),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
if spec['expected_output_file'] is not None:
|
||||
exp_output_file = os.path.join(test_profile_dir,
|
||||
spec['expected_output_file'])
|
||||
with open(exp_output_file, 'rb') as f:
|
||||
expected_output = f.read()
|
||||
assert expected_output == out
|
||||
else:
|
||||
assert out == b''
|
||||
|
||||
if spec['expected_err_file'] is not None:
|
||||
exp_err_file = os.path.join(test_profile_dir,
|
||||
spec['expected_err_file'])
|
||||
with open(exp_err_file, 'rb') as f:
|
||||
expected_err = f.read()
|
||||
assert expected_err == err
|
||||
else:
|
||||
assert err == b''
|
||||
|
||||
|
||||
@pytest.mark.parametrize('spec', test_spec)
|
||||
def test_all_tests_in_profile(spec):
|
||||
spec['command'] = final_command(spec['command'])
|
||||
if spec['method'] == 'cmp_with_file_contents':
|
||||
_test_cmp_with_file_contents(spec)
|
|
@ -0,0 +1 @@
|
|||
.env*
|
|
@ -0,0 +1,4 @@
|
|||
Warning!!! Possibly conflicting dependencies found:
|
||||
* Jinja2==2.11.1
|
||||
- MarkupSafe [required: >=0.23, installed: 0.22]
|
||||
------------------------------------------------------------------------
|
|
@ -0,0 +1,9 @@
|
|||
Flask==0.10.1
|
||||
- itsdangerous [required: >=0.21, installed: 0.24]
|
||||
- Jinja2 [required: >=2.4, installed: 2.11.1]
|
||||
- MarkupSafe [required: >=0.23, installed: 0.22]
|
||||
- Werkzeug [required: >=0.7, installed: 0.11.2]
|
||||
pipdeptree==2.0.0b1
|
||||
- pip [required: >=6.0.0, installed: 20.0.2]
|
||||
setuptools==46.1.3
|
||||
wheel==0.34.2
|
|
@ -0,0 +1,6 @@
|
|||
Flask==0.10.1
|
||||
itsdangerous==0.24
|
||||
Jinja2
|
||||
MarkupSafe==0.22
|
||||
Werkzeug==0.11.2
|
||||
argparse
|
|
@ -0,0 +1,11 @@
|
|||
itsdangerous==0.24
|
||||
- Flask==0.10.1 [requires: itsdangerous>=0.21]
|
||||
MarkupSafe==0.22
|
||||
- Jinja2==2.11.1 [requires: MarkupSafe>=0.23]
|
||||
- Flask==0.10.1 [requires: Jinja2>=2.4]
|
||||
pip==20.0.2
|
||||
- pipdeptree==2.0.0b1 [requires: pip>=6.0.0]
|
||||
setuptools==46.1.3
|
||||
Werkzeug==0.11.2
|
||||
- Flask==0.10.1 [requires: Werkzeug>=0.7]
|
||||
wheel==0.34.2
|
|
@ -0,0 +1,16 @@
|
|||
[
|
||||
{
|
||||
"id": "default_output",
|
||||
"method": "cmp_with_file_contents",
|
||||
"command": "{{pipdeptree}}",
|
||||
"expected_output_file": "default.out",
|
||||
"expected_err_file": "default.err"
|
||||
},
|
||||
{
|
||||
"id": "reverse_output",
|
||||
"method": "cmp_with_file_contents",
|
||||
"command": "{{pipdeptree}} -r",
|
||||
"expected_output_file": "reverse.out",
|
||||
"expected_err_file": "default.err"
|
||||
}
|
||||
]
|
|
@ -0,0 +1 @@
|
|||
.env*
|
|
@ -0,0 +1,4 @@
|
|||
Warning!! Cyclic dependencies found:
|
||||
* CircularDependencyB => CircularDependencyA => CircularDependencyB
|
||||
* CircularDependencyA => CircularDependencyB => CircularDependencyA
|
||||
------------------------------------------------------------------------
|
|
@ -0,0 +1,4 @@
|
|||
pipdeptree==2.0.0b1
|
||||
- pip [required: >=6.0.0, installed: 20.0.2]
|
||||
setuptools==46.1.3
|
||||
wheel==0.34.2
|
|
@ -0,0 +1,2 @@
|
|||
CircularDependencyA
|
||||
CircularDependencyB
|
|
@ -0,0 +1,9 @@
|
|||
[
|
||||
{
|
||||
"id": "default_output",
|
||||
"method": "cmp_with_file_contents",
|
||||
"command": "{{pipdeptree}}",
|
||||
"expected_output_file": "default.out",
|
||||
"expected_err_file": "default.err"
|
||||
}
|
||||
]
|
|
@ -0,0 +1 @@
|
|||
.env*
|
|
@ -0,0 +1,65 @@
|
|||
appnope==0.1.0
|
||||
backcall==0.1.0
|
||||
click==7.1.1
|
||||
decorator==4.4.2
|
||||
Flask==1.1.2
|
||||
- click [required: >=5.1, installed: 7.1.1]
|
||||
- itsdangerous [required: >=0.24, installed: 1.1.0]
|
||||
- Jinja2 [required: >=2.10.1, installed: 2.11.1]
|
||||
- MarkupSafe [required: >=0.23, installed: 1.1.1]
|
||||
- Werkzeug [required: >=0.15, installed: 1.0.1]
|
||||
Flask-Script==2.0.6
|
||||
- Flask [required: Any, installed: 1.1.2]
|
||||
- click [required: >=5.1, installed: 7.1.1]
|
||||
- itsdangerous [required: >=0.24, installed: 1.1.0]
|
||||
- Jinja2 [required: >=2.10.1, installed: 2.11.1]
|
||||
- MarkupSafe [required: >=0.23, installed: 1.1.1]
|
||||
- Werkzeug [required: >=0.15, installed: 1.0.1]
|
||||
gnureadline==8.0.0
|
||||
ipython==7.13.0
|
||||
- appnope [required: Any, installed: 0.1.0]
|
||||
- backcall [required: Any, installed: 0.1.0]
|
||||
- decorator [required: Any, installed: 4.4.2]
|
||||
- jedi [required: >=0.10, installed: 0.16.0]
|
||||
- parso [required: >=0.5.2, installed: 0.6.2]
|
||||
- pexpect [required: Any, installed: 4.8.0]
|
||||
- ptyprocess [required: >=0.5, installed: 0.6.0]
|
||||
- pickleshare [required: Any, installed: 0.7.5]
|
||||
- prompt-toolkit [required: >=2.0.0,<3.1.0,!=3.0.1,!=3.0.0, installed: 3.0.5]
|
||||
- wcwidth [required: Any, installed: 0.1.9]
|
||||
- pygments [required: Any, installed: 2.6.1]
|
||||
- setuptools [required: >=18.5, installed: 46.1.3]
|
||||
- traitlets [required: >=4.2, installed: 4.3.3]
|
||||
- decorator [required: Any, installed: 4.4.2]
|
||||
- ipython-genutils [required: Any, installed: 0.2.0]
|
||||
- six [required: Any, installed: 1.14.0]
|
||||
ipython-genutils==0.2.0
|
||||
itsdangerous==1.1.0
|
||||
jedi==0.16.0
|
||||
- parso [required: >=0.5.2, installed: 0.6.2]
|
||||
Jinja2==2.11.1
|
||||
- MarkupSafe [required: >=0.23, installed: 1.1.1]
|
||||
MarkupSafe==1.1.1
|
||||
parso==0.6.2
|
||||
pexpect==4.8.0
|
||||
- ptyprocess [required: >=0.5, installed: 0.6.0]
|
||||
pickleshare==0.7.5
|
||||
pip==20.0.2
|
||||
pipdeptree==2.0.0b1
|
||||
- pip [required: >=6.0.0, installed: 20.0.2]
|
||||
prompt-toolkit==3.0.5
|
||||
- wcwidth [required: Any, installed: 0.1.9]
|
||||
ptyprocess==0.6.0
|
||||
Pygments==2.6.1
|
||||
pymongo==3.10.1
|
||||
redis==3.4.1
|
||||
setuptools==46.1.3
|
||||
six==1.14.0
|
||||
slugify==0.0.1
|
||||
traitlets==4.3.3
|
||||
- decorator [required: Any, installed: 4.4.2]
|
||||
- ipython-genutils [required: Any, installed: 0.2.0]
|
||||
- six [required: Any, installed: 1.14.0]
|
||||
wcwidth==0.1.9
|
||||
Werkzeug==1.0.1
|
||||
wheel==0.34.2
|
|
@ -0,0 +1,31 @@
|
|||
Flask-Script==2.0.6
|
||||
- Flask [required: Any, installed: 1.1.2]
|
||||
- click [required: >=5.1, installed: 7.1.1]
|
||||
- itsdangerous [required: >=0.24, installed: 1.1.0]
|
||||
- Jinja2 [required: >=2.10.1, installed: 2.11.1]
|
||||
- MarkupSafe [required: >=0.23, installed: 1.1.1]
|
||||
- Werkzeug [required: >=0.15, installed: 1.0.1]
|
||||
gnureadline==8.0.0
|
||||
ipython==7.13.0
|
||||
- appnope [required: Any, installed: 0.1.0]
|
||||
- backcall [required: Any, installed: 0.1.0]
|
||||
- decorator [required: Any, installed: 4.4.2]
|
||||
- jedi [required: >=0.10, installed: 0.16.0]
|
||||
- parso [required: >=0.5.2, installed: 0.6.2]
|
||||
- pexpect [required: Any, installed: 4.8.0]
|
||||
- ptyprocess [required: >=0.5, installed: 0.6.0]
|
||||
- pickleshare [required: Any, installed: 0.7.5]
|
||||
- prompt-toolkit [required: >=2.0.0,<3.1.0,!=3.0.1,!=3.0.0, installed: 3.0.5]
|
||||
- wcwidth [required: Any, installed: 0.1.9]
|
||||
- pygments [required: Any, installed: 2.6.1]
|
||||
- setuptools [required: >=18.5, installed: 46.1.3]
|
||||
- traitlets [required: >=4.2, installed: 4.3.3]
|
||||
- decorator [required: Any, installed: 4.4.2]
|
||||
- ipython-genutils [required: Any, installed: 0.2.0]
|
||||
- six [required: Any, installed: 1.14.0]
|
||||
pipdeptree==2.0.0b1
|
||||
- pip [required: >=6.0.0, installed: 20.0.2]
|
||||
pymongo==3.10.1
|
||||
redis==3.4.1
|
||||
slugify==0.0.1
|
||||
wheel==0.34.2
|
|
@ -0,0 +1,17 @@
|
|||
ipython==7.13.0
|
||||
- appnope [required: Any, installed: 0.1.0]
|
||||
- backcall [required: Any, installed: 0.1.0]
|
||||
- decorator [required: Any, installed: 4.4.2]
|
||||
- jedi [required: >=0.10, installed: 0.16.0]
|
||||
- parso [required: >=0.5.2, installed: 0.6.2]
|
||||
- pexpect [required: Any, installed: 4.8.0]
|
||||
- ptyprocess [required: >=0.5, installed: 0.6.0]
|
||||
- pickleshare [required: Any, installed: 0.7.5]
|
||||
- prompt-toolkit [required: >=2.0.0,<3.1.0,!=3.0.1,!=3.0.0, installed: 3.0.5]
|
||||
- wcwidth [required: Any, installed: 0.1.9]
|
||||
- pygments [required: Any, installed: 2.6.1]
|
||||
- setuptools [required: >=18.5, installed: 46.1.3]
|
||||
- traitlets [required: >=4.2, installed: 4.3.3]
|
||||
- decorator [required: Any, installed: 4.4.2]
|
||||
- ipython-genutils [required: Any, installed: 0.2.0]
|
||||
- six [required: Any, installed: 1.14.0]
|
|
@ -0,0 +1,7 @@
|
|||
Flask==1.1.2
|
||||
Flask-Script==2.0.6
|
||||
gnureadline==8.0.0
|
||||
pymongo==3.10.1
|
||||
redis==3.4.1
|
||||
slugify==0.0.1
|
||||
ipython==7.13.0
|
|
@ -0,0 +1,49 @@
|
|||
appnope==0.1.0
|
||||
- ipython==7.13.0 [requires: appnope]
|
||||
backcall==0.1.0
|
||||
- ipython==7.13.0 [requires: backcall]
|
||||
click==7.1.1
|
||||
- Flask==1.1.2 [requires: click>=5.1]
|
||||
- Flask-Script==2.0.6 [requires: Flask]
|
||||
decorator==4.4.2
|
||||
- ipython==7.13.0 [requires: decorator]
|
||||
- traitlets==4.3.3 [requires: decorator]
|
||||
- ipython==7.13.0 [requires: traitlets>=4.2]
|
||||
gnureadline==8.0.0
|
||||
ipython-genutils==0.2.0
|
||||
- traitlets==4.3.3 [requires: ipython-genutils]
|
||||
- ipython==7.13.0 [requires: traitlets>=4.2]
|
||||
itsdangerous==1.1.0
|
||||
- Flask==1.1.2 [requires: itsdangerous>=0.24]
|
||||
- Flask-Script==2.0.6 [requires: Flask]
|
||||
MarkupSafe==1.1.1
|
||||
- Jinja2==2.11.1 [requires: MarkupSafe>=0.23]
|
||||
- Flask==1.1.2 [requires: Jinja2>=2.10.1]
|
||||
- Flask-Script==2.0.6 [requires: Flask]
|
||||
parso==0.6.2
|
||||
- jedi==0.16.0 [requires: parso>=0.5.2]
|
||||
- ipython==7.13.0 [requires: jedi>=0.10]
|
||||
pickleshare==0.7.5
|
||||
- ipython==7.13.0 [requires: pickleshare]
|
||||
pip==20.0.2
|
||||
- pipdeptree==2.0.0b1 [requires: pip>=6.0.0]
|
||||
ptyprocess==0.6.0
|
||||
- pexpect==4.8.0 [requires: ptyprocess>=0.5]
|
||||
- ipython==7.13.0 [requires: pexpect]
|
||||
pygments==2.6.1
|
||||
- ipython==7.13.0 [requires: pygments]
|
||||
pymongo==3.10.1
|
||||
redis==3.4.1
|
||||
setuptools==46.1.3
|
||||
- ipython==7.13.0 [requires: setuptools>=18.5]
|
||||
six==1.14.0
|
||||
- traitlets==4.3.3 [requires: six]
|
||||
- ipython==7.13.0 [requires: traitlets>=4.2]
|
||||
slugify==0.0.1
|
||||
wcwidth==0.1.9
|
||||
- prompt-toolkit==3.0.5 [requires: wcwidth]
|
||||
- ipython==7.13.0 [requires: prompt-toolkit>=2.0.0,<3.1.0,!=3.0.1,!=3.0.0]
|
||||
Werkzeug==1.0.1
|
||||
- Flask==1.1.2 [requires: Werkzeug>=0.15]
|
||||
- Flask-Script==2.0.6 [requires: Flask]
|
||||
wheel==0.34.2
|
|
@ -0,0 +1,30 @@
|
|||
[
|
||||
{
|
||||
"id": "default_output",
|
||||
"method": "cmp_with_file_contents",
|
||||
"command": "{{pipdeptree}}",
|
||||
"expected_output_file": "default.out",
|
||||
"expected_err_file": null
|
||||
},
|
||||
{
|
||||
"id": "reverse_output",
|
||||
"method": "cmp_with_file_contents",
|
||||
"command": "{{pipdeptree}} -r",
|
||||
"expected_output_file": "reverse.out",
|
||||
"expected_err_file": null
|
||||
},
|
||||
{
|
||||
"id": "--all_output",
|
||||
"method": "cmp_with_file_contents",
|
||||
"command": "{{pipdeptree}} --all",
|
||||
"expected_output_file": "all_flag.out",
|
||||
"expected_err_file": null
|
||||
},
|
||||
{
|
||||
"id": "--packages_output",
|
||||
"method": "cmp_with_file_contents",
|
||||
"command": "{{pipdeptree}} --packages pexpect,ipython",
|
||||
"expected_output_file": "packages_opt.out",
|
||||
"expected_err_file": null
|
||||
}
|
||||
]
|
Loading…
Reference in New Issue