Skip to content

Commit 93d4bda

Browse files
authored
Merge pull request #52 from Charlesworth/feature/api-tests
API/SDK integration test setup
2 parents dd43ef9 + 58d3935 commit 93d4bda

File tree

5 files changed

+89
-22
lines changed

5 files changed

+89
-22
lines changed

Pipfile

+3
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ pytest = "*"
1313
"pytest-cov" = "*"
1414

1515
[requires]
16+
17+
[scripts]
18+
test = "python -m pytest tests/"

README.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,19 @@ Please raise any bugs or feature requests as a Github issues. We also gratefully
157157
## Testing
158158

159159
```bash
160+
# to run all test files in tests directory
161+
$ pipenv run test
162+
163+
# or to run a single test file
160164
$ pipenv shell
161-
$ python -m pytest evasdk/<name-of-file-to-test>
165+
$ python -m pytest tests/<test-name>_test.py
162166

163167
# some test require supplying ip and token via the `--ip` and `--token` arguements
164-
$ python -m pytest evasdk/<name-of-file-to-test> --ip 172.16.16.2 --token abc-123-def-456
168+
$ pipenv run test --ip 172.16.16.2 --token abc-123-def-456
169+
170+
# long duration tests and tests requiring a connected Eva are disabled by default,
171+
# to include them add the `--runslow` or --runrobot flags
172+
$ pipenv run test --runslow --runrobot
165173
```
166174

167175
## License

tests/eva_auth_test2.py renamed to tests/Eva_auth_test.py

+4-20
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,11 @@
1-
from evasdk import Eva, EvaAutoRenewError, EvaError
1+
from evasdk import EvaAutoRenewError, EvaError
22
import time
33
import pytest
4-
import logging
54

65
# TODO: this rely on having an actual robot, should be rewritten to be mockable
76

87

9-
@pytest.fixture(scope="module")
10-
def eva(ip, token):
11-
e = Eva(ip, token, request_timeout=10, renew_period=2 * 60)
12-
e._Eva__logger.setLevel(logging.DEBUG)
13-
e._Eva__http_client._EvaHTTPClient__logger.setLevel(logging.DEBUG)
14-
yield e
15-
if e.lock_status()['status'] != 'unlocked':
16-
e.unlock()
17-
18-
19-
@pytest.fixture
20-
def locked_eva(eva):
21-
with eva.lock():
22-
yield eva
23-
24-
8+
@pytest.mark.robot_required
259
class TestAuth:
2610
def test_create_new_session(self, eva):
2711
token = eva.auth_create_session()
@@ -38,7 +22,7 @@ def test_invalidate_session(self, eva):
3822
eva.users_get()
3923
assert(token != eva._Eva__http_client.session_token)
4024

41-
25+
@pytest.mark.slow
4226
def test_auto_renew_error(self, eva):
4327
api_token = eva._Eva__http_client.api_token
4428
eva._Eva__http_client.api_token = ''
@@ -69,7 +53,7 @@ def test_lock_with_no_existing_session(self, eva):
6953
with eva.lock():
7054
eva.gpio_set('d1', not eva.gpio_get('d1', 'output'))
7155

72-
56+
@pytest.mark.slow
7357
def test_auto_renew(self, locked_eva):
7458
for _ in range(7):
7559
locked_eva.gpio_set('d1', not locked_eva.gpio_get('d1', 'output'))

tests/Eva_data_test.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from evasdk import EvaError
2+
import pytest
3+
4+
5+
@pytest.mark.robot_required
6+
class TestEva_Data:
7+
# TODO: we may want to check the structure of the snapshot JSON object
8+
def test_snapshot(self, eva):
9+
snapshot = eva.data_snapshot()
10+
assert(snapshot)
11+
assert(snapshot['control']['loop_count'] >= 0)
12+
13+
14+
def test_snapshot_property(self, eva):
15+
control_snapshot = eva.data_snapshot_property('control')
16+
assert(control_snapshot)
17+
assert(control_snapshot['loop_count'] >= 0)
18+
19+
20+
def test_data_snapshot_property_PropertNotPresent(self, eva):
21+
with pytest.raises(EvaError):
22+
eva.data_snapshot_property('rubbish_property')
23+
24+
25+
def test_servo_positions(self, eva):
26+
servo_positions = eva.data_servo_positions()
27+
assert(len(servo_positions) == 6)

tests/conftest.py

+45
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
from evasdk import Eva
12
import pytest
3+
import logging
24

35

46
def pytest_addoption(parser):
57
parser.addoption("--ip", default='172.16.16.2', help="IP of the test robot, defaults to 172.16.16.2")
68
parser.addoption("--token", default='', help="API token of the test robot")
9+
parser.addoption("--runslow", action="store_true", default=False, help="run slow tests")
10+
parser.addoption("--runrobot", action="store_true", default=False, help="run tests that require a connected Eva")
711

812

913
@pytest.fixture(scope="session")
@@ -14,3 +18,44 @@ def ip(request):
1418
@pytest.fixture(scope="session")
1519
def token(request):
1620
return request.config.getoption("--token")
21+
22+
23+
def pytest_configure(config):
24+
config.addinivalue_line("markers", "slow: mark test as slow to run")
25+
config.addinivalue_line("markers", "robot_required: no mocks, needs a connected Eva to run")
26+
27+
28+
def pytest_collection_modifyitems(config, items):
29+
if config.getoption("--runslow"):
30+
# --runslow given in cli: do not skip slow tests
31+
return
32+
else:
33+
skip_slow = pytest.mark.skip(reason="need --runslow option to run")
34+
for item in items:
35+
if "slow" in item.keywords:
36+
item.add_marker(skip_slow)
37+
38+
if config.getoption("--runrobot"):
39+
# --runrobot given in cli: do not skip tests where a connected Eva is required
40+
return
41+
else:
42+
skip_robot_required = pytest.mark.skip(reason="need --runrobot option to run")
43+
for item in items:
44+
if "robot_required" in item.keywords:
45+
item.add_marker(skip_robot_required)
46+
47+
48+
@pytest.fixture(scope="module")
49+
def eva(ip, token):
50+
e = Eva(ip, token, request_timeout=10, renew_period=2 * 60)
51+
e._Eva__logger.setLevel(logging.DEBUG)
52+
e._Eva__http_client._EvaHTTPClient__logger.setLevel(logging.DEBUG)
53+
yield e
54+
if e.lock_status()['status'] != 'unlocked':
55+
e.unlock()
56+
57+
58+
@pytest.fixture
59+
def locked_eva(eva):
60+
with eva.lock():
61+
yield eva

0 commit comments

Comments
 (0)