Skip to content

Commit 7526a29

Browse files
authored
Introduce httpretty for unittest to mock Appium server (appium#281)
* add httpretty * add clipboard tests as an example * add test for forceMjsonwp
1 parent 76008c6 commit 7526a29

12 files changed

Lines changed: 271 additions & 34 deletions

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
language: python
2+
dist: xenial
3+
24
python:
35
- "2.7"
6+
- "3.4"
7+
- "3.5"
48
- "3.6"
9+
- "3.7"
510

611
install:
712
- pip install -r ci-requirements.txt

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,24 @@ download and unarchive the source tarball (Appium-Python-Client-X.X.tar.gz).
4646
```
4747
- You can customise `CHANGELOG.rst` with commit messages following [.gitchangelog.rc](.gitchangelog.rc)
4848
- It generates readable changelog
49+
- `pip install -r development.txt`
4950

5051
## Run tests
5152

53+
### Unit
54+
55+
```
56+
$ py.test test/unit
57+
```
58+
59+
Run with `pytest-xdist`
60+
61+
```
62+
$ py.test -n 2 test/unit
63+
```
64+
65+
### Functional
66+
5267
```
5368
$ py.test test/functional/ios/find_by_ios_class_chain_tests.py
5469
```

ci-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ astroid==1.6.5
33
isort==4.3.4
44
pylint==1.9.3
55
autopep8==1.4.3
6+
httpretty==0.9.6

ci.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ if [[ $result ]] ; then
88
fi
99

1010
python -m pylint --rcfile .pylintrc appium test --py3k
11-
python -m pytest test/unit/*
11+
python -m pytest test/unit/

development.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-r ci-requirements.txt

test/unit/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env python
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.

test/unit/helper/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/usr/bin/env python
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.

test/unit/helper/test_helper.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env python
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import unittest
16+
import httpretty
17+
import json
18+
19+
from appium import webdriver
20+
21+
22+
class TestHelper():
23+
24+
@staticmethod
25+
def mock_android_driver():
26+
"""
27+
Return a driver which is generated a mock response
28+
29+
:return: An instance of WebDriver
30+
:rtype: WebDriver
31+
"""
32+
33+
response_body_json = json.dumps(
34+
{
35+
'value': {
36+
'sessionId': '1234567890',
37+
'capabilities': {
38+
'platform': 'LINUX',
39+
'desired': {
40+
'platformName': 'Android',
41+
'automationName': 'uiautomator2',
42+
'platformVersion': '7.1.1',
43+
'deviceName': 'Android Emulator',
44+
'app': '/test/apps/ApiDemos-debug.apk',
45+
},
46+
'platformName': 'Android',
47+
'automationName': 'uiautomator2',
48+
'platformVersion': '7.1.1',
49+
'deviceName': 'emulator-5554',
50+
'app': '/test/apps/ApiDemos-debug.apk',
51+
'deviceUDID': 'emulator-5554',
52+
'appPackage': 'com.example.android.apis',
53+
'appWaitPackage': 'com.example.android.apis',
54+
'appActivity': 'com.example.android.apis.ApiDemos',
55+
'appWaitActivity': 'com.example.android.apis.ApiDemos'
56+
}
57+
}
58+
}
59+
)
60+
61+
httpretty.register_uri(
62+
httpretty.POST,
63+
'http://localhost:4723/wd/hub/session',
64+
body=response_body_json
65+
)
66+
67+
desired_caps = {
68+
'platformName': 'Android',
69+
'deviceName': 'Android Emulator',
70+
'app': 'path/to/app',
71+
'automationName': 'UIAutomator2'
72+
}
73+
driver = webdriver.Remote(
74+
'http://localhost:4723/wd/hub',
75+
desired_caps
76+
)
77+
return driver
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env python
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from test.unit.helper.test_helper import TestHelper
16+
17+
import json
18+
import httpretty
19+
20+
21+
class TestWebDriverDeviceClipboard(object):
22+
23+
@httpretty.activate
24+
def test_clipboard(self):
25+
driver = TestHelper.mock_android_driver()
26+
httpretty.register_uri(
27+
httpretty.POST,
28+
'http://localhost:4723/wd/hub/session/1234567890/appium/device/set_clipboard',
29+
body='{"value": ""}'
30+
)
31+
driver.set_clipboard_text('hello')
32+
33+
d = json.loads(httpretty.last_request().body.decode('utf-8'))
34+
assert d['content'] == 'aGVsbG8='
35+
assert d['contentType'] == 'plaintext'
Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,17 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import unittest
16-
15+
import pytest
1716
from appium.webdriver.common.multi_action import MultiAction
1817
from appium.webdriver.common.touch_action import TouchAction
1918

2019

21-
class MultiActionTests(unittest.TestCase):
22-
def setUp(self):
23-
self._multi_action = MultiAction(DriverStub())
20+
class TestMultiAction(object):
21+
@pytest.fixture
22+
def multi_action(self):
23+
return MultiAction(DriverStub())
2424

25-
def test_json(self):
26-
self.maxDiff = None
25+
def test_json(self, multi_action):
2726
json = {
2827
'actions': [
2928
[
@@ -40,23 +39,19 @@ def test_json(self):
4039
}
4140
t1 = TouchAction(DriverStub()).press(ElementStub(1)).move_to(x=10, y=20).release()
4241
t2 = TouchAction(DriverStub()).press(ElementStub(5), 11, 30).move_to(x=12, y=-300).release()
43-
self._multi_action.add(t1, t2)
44-
self.assertEqual(json, self._multi_action.json_wire_gestures)
42+
multi_action.add(t1, t2)
43+
assert json == multi_action.json_wire_gestures
4544

4645

4746
class DriverStub(object):
48-
def execute(self, action, params):
47+
def execute(self, _action, _params):
4948
print("driver.execute called")
5049

5150

5251
class ElementStub(object):
53-
def __init__(self, id):
54-
self._id = id
52+
def __init__(self, e_id):
53+
self._id = e_id
5554

5655
@property
5756
def id(self):
5857
return self._id
59-
60-
61-
if __name__ == "__main__":
62-
unittest.main()

0 commit comments

Comments
 (0)