Skip to content

Commit a01594f

Browse files
committed
Draft: replace nosetests with pytest
1 parent ec648db commit a01594f

27 files changed

+182
-219
lines changed

Gruntfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ module.exports = function (grunt) {
9595
}
9696
},
9797
test_server_functional: {
98-
command: 'nosetests3 tests/functional/'
98+
command: 'pytest tests/functional/'
9999
},
100100
test_client: {
101101
command: 'npm run test'

controllers/default.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1807,7 +1807,7 @@ def licence():
18071807
return dict()
18081808

18091809
def news():
1810-
redirect(URL('default', 'milestones.html'))
1810+
redirect(URL('default', 'timeline.html'))
18111811
return dict()
18121812

18131813

tests/benchmarking/API/test_textsearch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ class TestTextsearch(object):
168168
replicates = 3
169169

170170
@classmethod
171-
def setUpClass(self):
171+
def setup_class(self):
172172
self.web2py = Web2py_server()
173173
wait_for_server_active()
174174
colorama.init()

tests/benchmarking/test_viewer_loading.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
"""
33
"""
44

5-
from ...util import base_url
6-
from ..functional_tests import FunctionalTest
5+
from ..util import base_url
6+
from ..functional.functional_tests import FunctionalTest
77
import os.path
88

99
class TestViewerLoading(FunctionalTest):
1010
"""
1111
Test whether the viewer loading functions work
1212
"""
1313
@classmethod
14-
def setUpClass(self):
14+
def setup_class(self):
1515
print("== Running {} ==".format(os.path.basename(__file__)))
16-
super().setUpClass()
16+
super().setup_class()
1717

1818
def test_viewer_loading_time(self):
1919
"""

tests/functional/functional_tests.py

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,26 @@
33
"""Carry out functional tests on OneZoom pages using an automated browser via selenium
44
55
Example: carry out all tests
6-
nosetests -w ./ tests/functional
6+
python -m pytest ./ tests/functional
77
Example: carry out all tests for unsponsorable sites (museum displays)
8-
nosetests -vs functional/sponsorship/test_unsponsorable_site.py
8+
python -m pytest -s functional/sponsorship/test_unsponsorable_site.py
99
Example: carry out test that unsponsorable sites give the correct page for invalid otts
10-
nosetests -vs functional/sponsorship/test_unsponsorable_site.py:TestUnsponsorableSite.test_invalid
11-
12-
If you have installed the 'rednose' package (pip3 install rednose), you can get nicer output by e.g.
13-
14-
nosetests -vs ./tests/functional --rednose
10+
python -m pytest -s functional/sponsorship/test_unsponsorable_site.py:TestUnsponsorableSite.test_invalid
1511
1612
To carry out tests on a remote machine, you can specify a [url][server] and [url][port]
1713
in a config file, which will not give the FunctionalTest class an is_local attribute
1814
and hence will skip tests marked @attr('is_local'). E.g. for testing beta.onezoom.org, you can do
19-
15+
TODO: this is not yet implemented for the functional tests
16+
in nosetests we used to do...
2017
nosetests -vs ./tests/functional --rednose --tc-file beta_cfg.ini
21-
18+
2219
"""
2320

2421
import sys
2522
import json
2623
import os
2724
import re
2825
from datetime import datetime
29-
from nose import tools
3026
import requests
3127
import subprocess
3228
import logging
@@ -52,7 +48,7 @@ class FunctionalTest(object):
5248
is_local = Web2py_server.is_local()
5349

5450
@classmethod
55-
def setUpClass(self):
51+
def setup_class(self):
5652
def striptext_in_file(line, file):
5753
"""
5854
look for the line as a starting line in the file, stripping whitespace
@@ -97,55 +93,50 @@ def striptext_in_file(line, file):
9793
selenium_logger.setLevel(logging.WARNING)
9894
#chrome_options = webdriver.ChromeOptions()
9995
#chrome_options.add_experimental_option("mobileEmulation", { "deviceName": "iPhone 7" })
100-
self.caps = webdriver.ChromeOptions().to_capabilities()
96+
chrome_options = webdriver.ChromeOptions()
10197
# enable browser logging
102-
self.caps['loggingPrefs'] = { 'browser':'ALL' }
103-
self.browser = webdriver.Chrome(desired_capabilities = self.caps)
98+
chrome_options.set_capability('goog:loggingPrefs', { 'browser':'ALL' })
99+
self.browser = webdriver.Chrome(options=chrome_options)
104100
self.browser.implicitly_wait(1)
105101

106102
@classmethod
107-
def tearDownClass(self):
103+
def teardown_class(self):
108104
#should test here that we don't have any console.log errors (although we might have logs).
109105
self.browser.quit()
110106
self.web2py.stop_server()
111107

112-
def setup(self):
108+
def setup_method(self):
113109
"""
114110
By default, clear logs before each test
115111
"""
116112
self.clear_log()
117113

118-
def teardown(self):
114+
def teardown_method(self):
119115
"""
120116
By default, check javascript errors after each test. If you don't want to do this, e.g. for iframes, thic can be overridden
121117
"""
122118
self.clear_log(check_errors=True)
123119

124-
@tools.nottest
125120
def element_by_tag_name_exists(self, tag_name):
126-
try: self.browser.find_element_by_tag_name(tag_name)
121+
try: self.browser.find_element(By.TAG_NAME, tag_name)
127122
except NoSuchElementException: return False
128123
return True
129124

130-
@tools.nottest
131125
def element_by_id_exists(self, id):
132-
try: self.browser.find_element_by_id(id)
126+
try: self.browser.find_element(By.ID, id)
133127
except NoSuchElementException: return False
134128
return True
135129

136-
@tools.nottest
137130
def element_by_class_exists(self, cls):
138-
try: self.browser.find_element_by_class_name(cls)
131+
try: self.browser.find_element(By.CLASS_NAME, cls)
139132
except NoSuchElementException: return False
140133
return True
141134

142-
@tools.nottest
143135
def element_by_css_selector_exists(self, css):
144-
try: self.browser.find_element_by_css_selector(css)
136+
try: self.browser.find_element(By.CSS_SELECTOR, css)
145137
except NoSuchElementException: return False
146138
return True
147139

148-
@tools.nottest
149140
def clear_log(self, check_errors=False):
150141
log = self.browser.get_log('browser')
151142
if check_errors:
@@ -155,7 +146,6 @@ def clear_log(self, check_errors=False):
155146
if not (message['message'].startswith("https://media.eol.org/content") and "404 (Not Found)" in message['message']):
156147
assert False, "Javascript issue of level {}, : {}".format(message['level'], message['message'])
157148

158-
@tools.nottest
159149
def zoom_disabled(self):
160150
"""
161151
Check that the touch zoom functionality is disabled.
@@ -209,17 +199,17 @@ def has_linkouts(browser, include_site_internal):
209199
Depending on the param passed in, we may want to allow internal (relative) links such as
210200
<a href='/sponsored'></a>
211201
"""
212-
for tag in browser.find_elements_by_css_selector("[href^='http']"):
202+
for tag in browser.find_elements(By.CSS_SELECTOR, "[href^='http']"):
213203
if tag.tag_name != u'link' and not tag.get_attribute('href').startswith('http://127.0.0.1'): #should allow e.g. <link href="styles.css"> and http://127.0.0.1:..
214204
return True
215-
for tag in browser.find_elements_by_css_selector("[href^='//']"):
205+
for tag in browser.find_elements(By.CSS_SELECTOR, "[href^='//']"):
216206
if tag.tag_name != u'link': #should allow e.g. <link href="styles.css">
217207
return True
218208

219209
#all hrefs should now be http or https refs to local stuff. We should double check this
220210
#by looking at the tag.attribute which is fully expanded by selenium/chrome to include http
221211
#but we should exclude all page-local links (i.e. beginning with #)
222-
for tag in browser.find_elements_by_css_selector('[href]:not([href^="#"])'):
212+
for tag in browser.find_elements(By.CSS_SELECTOR, '[href]:not([href^="#"])'):
223213
if tag.tag_name != u'link':
224214
if include_site_internal:
225215
return True
@@ -234,13 +224,13 @@ def has_linkouts(browser, include_site_internal):
234224
def web2py_date_accessed(browser):
235225
#assumes that we have injected the access date into a meta element called 'date_accessed'
236226
#using the web2py code {{response.meta.date_accessed = request.now}}
237-
return datetime.strptime(browser.find_element_by_xpath("//meta[@name='date_accessed']").get_attribute("content"), date_format)
227+
return datetime.strptime(browser.find_element(By.XPATH, "//meta[@name='date_accessed']").get_attribute("content"), date_format)
238228

239229
def web2py_viewname_contains(browser, expected_view):
240230
#Checks if we have injected the view name into a meta element called 'viewfile'
241231
#using the web2py code {{response.meta.viewfile = response.view}}
242232
try:
243-
return expected_view in browser.find_element_by_xpath("//meta[@name='viewfile']").get_attribute("content")
233+
return expected_view in browser.find_element(By.XPATH, "//meta[@name='viewfile']").get_attribute("content")
244234
except NoSuchElementException:
245235
return False
246236

tests/functional/sponsorship/sponsorship_tests.py

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
# -*- coding: utf-8 -*-
33
import os
44
import requests
5-
from nose import tools
6-
from time import sleep
75

86
from selenium import webdriver #to fire up a duplicate page
97

@@ -17,7 +15,7 @@ class SponsorshipTest(FunctionalTest):
1715
"""
1816

1917
@classmethod
20-
def setUpClass(self):
18+
def setup_class(self):
2119
"""
2220
When setting up the sponsorship pages testing suite we have to create a new appconfig.ini file
2321
and point out web2py instance at it so that we can adjust maintenance_mins and allow_sponsorship
@@ -33,7 +31,7 @@ def setUpClass(self):
3331
if line.lstrip().startswith("[sponsorship]"):
3432
test.write("maintenance_mins = {}\n".format(self.maintenance_mins))
3533
test.write("allow_sponsorship = {}\n".format(self.allow_sponsorship))
36-
super().setUpClass()
34+
super().setup_class()
3735

3836
#Now get s, from the "normal" OZ viewer, from a museum display,
3937
#from a partner view and also a test case where all links are banned
@@ -58,13 +56,12 @@ def setUpClass(self):
5856
}
5957

6058
@classmethod
61-
def tearDownClass(self):
62-
super().tearDownClass()
59+
def teardown_class(self):
60+
super().teardown_class()
6361
print(">> removing temporary appconfig")
6462
os.remove(self.appconfig_loc)
6563

66-
@tools.nottest
67-
def test_ott(self, extra_assert_tests, ott, extra_assert_tests_from_another_browser=None, browser=None):
64+
def check_ott(self, extra_assert_tests, ott, extra_assert_tests_from_another_browser=None, browser=None):
6865
"""
6966
Test the 4 separate urls, each viewing the same page linked from a different place
7067
(e.g. from the OZ tree viewer versus the min website, vs a museum display)
@@ -85,7 +82,7 @@ def test_ott(self, extra_assert_tests, ott, extra_assert_tests_from_another_brow
8582
#still forwards to the same page
8683
print(" ... also testing same pages from an alternative browser ...", end="", flush=True)
8784
alt_browser = webdriver.Chrome()
88-
self.test_ott(extra_assert_tests_from_another_browser, ott, None, alt_browser)
85+
self.check_ott(extra_assert_tests_from_another_browser, ott, None, alt_browser)
8986
alt_browser.quit()
9087
#check all the alternative representations too
9188
print("|w2p", end="", flush=True)
@@ -107,29 +104,7 @@ def test_ott(self, extra_assert_tests, ott, extra_assert_tests_from_another_brow
107104
assert has_linkouts(browser, include_site_internal=True) == False
108105
assert self.zoom_disabled()
109106
print(" ", end="", flush=True)
110-
111-
@tools.nottest
112-
def test_md_sandbox(self, ott):
113-
"""
114-
Follow any links from the museum display page and collect a list. If any are external, return False
115-
"""
116-
self.browser.get(self.urls['treeviewer_md'](ott))
117-
#Although any element can potentially link out to another page using javascript,
118-
# the most likely elements that will cause a sandbox escape on our own page
119-
# are <a href=...> <form action=...> <area href=...>, or <button onclick=...>
120-
# For external pages (e.g. wikipages) we shoud ensure that JS is stripped.
121-
def first_external_link(self, already_followed):
122-
"""
123-
Recurse through possible links from this page until we find an external one
124-
in which case we can return False, or
125-
"""
126-
return
127-
128-
for elem in self.browser.find_elements_by_tag_name('a'):
129-
href = elem.get_attribute('href')
130-
131107

132-
@tools.nottest
133108
def never_looked_at_ottname(self):
134109
"""
135110
Find an unpopular species that has never been looked at (i.e. does not have an entry in the reservations table
@@ -151,7 +126,6 @@ def never_looked_at_ottname(self):
151126
db_cursor.close()
152127
return ott, sciname
153128

154-
@tools.nottest
155129
def delete_reservation_entry(self, ott, name, email=test_email):
156130
"""
157131
Warning: this will REMOVE data. Make sure that this is definitely one of the previously not looked at species
@@ -170,30 +144,26 @@ def delete_reservation_entry(self, ott, name, email=test_email):
170144
db_cursor.close()
171145
return n_rows
172146

173-
@tools.nottest
174147
def invalid_ott(self):
175148
"""
176149
Give an invalid OTT. We should also test for 'species' with no space in the name, but we can't be guaranteed
177150
that there will be any of these
178151
"""
179152
return -1
180153

181-
@tools.nottest
182154
def banned_unsponsored_ott(self):
183155
"""
184156
Human ott is always banned, never sponsored
185157
"""
186158
return self.humanOTT
187159

188-
@tools.nottest
189160
def banned_sponsored_ott(self):
190161
"""
191162
We could possibly pick pandas here, but we are not assured that they will be sponsored on all sites
192163
"""
193164
raise NotImplementedError
194165

195166

196-
@tools.nottest
197167
def sponsored_ott(self):
198168
"""
199169
We might also want to test a sponsored banned species here, like the giant panda
@@ -206,7 +176,6 @@ def sponsored_ott(self):
206176
else:
207177
return sponsored[0]['OTT_ID']
208178

209-
@tools.nottest
210179
def visit_data(self, ott):
211180
"""
212181
Return the num_views, last_view and the reserve_time for this ott

0 commit comments

Comments
 (0)