How to get started with Nose in Python
Translator | Li Rui
Reviewer | Sun Shujuan
In this Python Nose tutorial, we'll delve into the Nose framework. Nose is a test automation framework that extends unittest and further utilizes Nose to perform Selenium test automation.
One of the challenges that many developers face in Selenium test automation is how to choose the right testing framework that will help them automate their tests with minimal (or no) boilerplate code. Most people come across test code and have to write a lot of code to perform simple tests.
Choosing the right test automation framework can significantly simplify a developer's job dealing with test code. Tests can be written taking advantage of the framework capabilities to perform the work with minimal implementation. As far as Selenium Python testing is concerned, there are several test automation frameworks to choose from such as PyUnit, Pytest, Robot, Cucumber, etc.
Python's standard unittest module was superseded by other Python test automation frameworks because it required a lot of boilerplate code and its tests had to be contained in large test classes. Nose is a popular alternative if developers still want to use the default Python unit testing framework. It has a powerful set of features that extend unittest to make testing easier. In this Python Nose tutorial, take a deep dive into the Nose framework and how to leverage Nose to perform Selenium test automation (using unittest) more efficiently.
Introduction to Nose Framework
Nose is a popular test automation framework in Python that extends unittest to make testing easier. Other advantages of using the Nose framework are support for automatic discovery of test cases and documentation collection.
The Nose framework has a rich set of plugins that help with test execution, parallel (or multi-process) testing, logging and reporting, and more. It can also run documentation tests, unit tests, and non-boilerplate tests. These plugins also add support for decorators, fixtures, parameterized tests, classes and modules.
The latest version of Nose is Nose 2, however, a large part of the developer and testing ecosystem is still using an older version of Nose, version 1.3.7.
Hence, the Python Nose tutorial series for Selenium test automation is divided into two parts, this one focuses on Selenium Python testing using Nose 1.3.7.
How to install the Nose framework
The Nose framework can be installed by executing the following command on the terminal:
pip install nose
As shown in the installation screenshot below, the installed version is 1.3.7. Since nose and nose 2 are two independent projects, the installation commands are different.
You can use import nose to import the Nose package in your code, but this step is optional. If you use a specific module in Nose, you must import the same module in your code using import Nose.<module_name>.
How to perform a nose test
Since the Nose module is installed for existing Python distributions as well as nosetests.exe, tests using the Nose framework can be executed by firing either of the following commands:
(1) Option 1
Shell
1 nosetests <file_name.py>
(2) Option 2
Shell
1 python -m nose <file_name.py>
Test Discovery Using the Nose Framework
Here are some simple rules the tests discovered:
- Like other Python automation frameworks, Nose also automates all tests present in the parent folder (and its subfolders).
- Modules (or files) chosen by the framework should start with "test_".
- Test methods must start with "test_".
- Test classes containing test methods should start with "test".
Like other Python automation frameworks, Nose also automates all tests present in the parent folder (and its subfolders).
Modules (or files) chosen by the framework should start with "test_".
Test methods must start with "test_".
Test classes containing test methods should start with "test".
These are some naming conventions that will be used for Selenium python tests using Nose. This set of rules is sufficient for test automation, and one can view the full set of rules in the "Find Tests" section of the Nose website.
Example usage of the Nose framework
The nomenclature followed in the unittest framework also applies to the Nose framework.
To demonstrate the use of the Nose framework in this Python Nose tutorial, a simple Selenium test automation example is used where a Google search for "LambdaTest" is performed and a click action is performed on the first result.
Python
1 from selenium import webdriver
2 import time
3 from time import sleep
4 from selenium.webdriver.common.by import By
5
6 def test_google_search:
7driver = webdriver. Chrome
8driver.get( 'https://www.google.com')
9 driver.maximize_window
10 title = "Google"
11 assert title == driver.title
12
13 search_text = "LambdaTest"
14 # search_box = driver.find_element_by_xpath("//input[@name='q']")
15 search_box = driver.find_element(By.XPATH, "//input[@name='q']")
16 search_box.send_keys(search_text)
17
18 # Using Sleep is not a good programming practice
19 # Only used here for demonstration purpose
20 time.sleep(5)
21 search_box.submit
22
23 time.sleep(5)
24
25 # Click on the LambdaTest HomePage Link
26 # This test will fail as the titles will not match
27 title = "Most Powerful Cross Browser Testing Tool Online | LambdaTest"
28 # lt_link = driver.find_element_by_xpath("//h3[.='LambdaTest: Most Powerful Cross Browser Testing Tool Online']")
29 lt_link = driver.find_element(By.XPATH, "//h3[.='LambdaTest: Most Powerful Cross Browser Testing Tool Online']")
30 lt_link.click
31
32 time.sleep(10)
33 assert title == driver.title
34 time.sleep(2)
35
36 # Release the resources in the teardown function
37 print( "TearDown initiated")
38 driver.quit
39
Swipe left and right to view the complete code
As can be seen from the implementation, the Nose module is not imported. The implementation is more or less identical to the one used by other Python automation frameworks. Therefore, the implementation aspects of the tests will not be delved deeper. The following figure is a screenshot of the execution:
The main advantage of using Nose (over the standard unittest module) is that it automatically collects tests, allowing the flexibility to write simple test functions or test classes that are not subclasses of unittest.TestCase.
Fixtures in the Nose framework
The Nose framework supports Fixtures (setup and teardown methods) at the test, package, class and module level. This helps eliminate unnecessary initializations that could hamper the performance of your tests if performed frequently.
As with py.test or unittest fixtures, the setup method is always run before any test (or collection of tests), and if the setup method executes successfully, the teardown method is run. This is independent of the state of the test run. Nose extends the unit test Fixtures model for setup (and teardown).
Fixtures can be implemented at the following levels:
test package
Tests can be grouped into test packages. So instead of creating a setup and teardown method that runs once per module or test case, the test package's setup and teardown methods are run once per test run.
To create setup and teardown for test package execution, the corresponding methods should be defined in the test package's init.py. Its nomenclature is as follows:
Python
1 Setup - setup, setup_package, setUp, or setUpPackage
2 TearDown - teardown, teardown_package, tearDown or tearDownPackage
Swipe left and right to view the complete code
test module
This enables defining setup and teardown methods at the test package level. The corresponding methods will be executed at the beginning and end of the module. Its nomenclature is as follows:
Python
1 Setup - setup, setup_module, setUp or setUpModule
2 TearDown - teardown, teardown_module, or tearDownModule
Swipe left and right to view the complete code
test function
This allows developers to define setup and teardown at the function level. As the names suggest, setup_function and teardown_function are executed before and after the test function call.
There is no specific naming convention, except that the setup method must be applied using the @with_setupdecorators imported from Nose. It is a widely used decorator and its usage will be demonstrated in the following examples.
test class
A test class is a class defined in the test module that matches test_Match, or a subclass of unittest.TestCase. The respective setup and teardown functions are run at the beginning and end of the test method class. The following is the nomenclature for setting Fixtures at the class level:
Python
1 Setup - setup_class, setupClass, setUpClass, setupAll (or setUpAll)
2 TearDown - teardown_class, teardownClass, tearDownClass, teardownAll (or tearDownAll)
Swipe left and right to view the complete code
In addition to following proper naming conventions, setup methods should be applied with @classmethoddecorators.
To demonstrate the use of Fixtures, Nose fixtures are used at different levels - classes, modules and methods.
Python
1 import nose
2 from nose.tools import with_setup
3
4 # Can also be setup, setup_module, setUp or setUpModule
5 def setUpModule(module):
6 print( "")
7 print( "%s"% (setUpModule.name,))
8
9 # Can also be teardown, teardown_module, or tearDownModule
10 def tearDownModule(module):
11 print( "%s"% (tearDownModule.name,))
12
13 def setup_func:
14 print( "%s"% (setup_func.name,))
15
16 def teardown_func:
17 print( "%s"% (teardown_func.name,))
18
19 @with_setup(setup_func, teardown_func)
20 def test_case_1:
21 print( "%s"% (test_case_1.name,))
22
23 class test_class_1:
24
25 def setup(self):
26 print( "%s called before each test method"% (test_class_1.setup.name,))
27
28 def teardown(self):
29 print( "%s called after each test method"% (test_class_1.teardown.name,))
30
31 @classmethod
32 def setup_class(cls):
33 print( "%s called before any method in this class is executed"% (test_class_1.setup_class.name,))
34
35 @classmethod
36 def teardown_class(cls):
37 print( "%s called after methods in this class is executed"% (test_class_1.teardown_class.name,))
38
39 def test_case_2(self):
40 print( "%s"% (test_class_1.test_case_2.name,))
Swipe left and right to view the complete code
Use the -s (or -nocapture) option in nosetests.exe so that any stdout output is captured immediately. The following commands are used to trigger execution:
Python
1 nosetests --verbose --nocapture Nose_Fixture_Example.py
Swipe left and right to view the complete code
Here's a screenshot of the output:
As shown in the proceeding screenshot, the module-level setup method runs at the beginning of execution, and the module-level teardown method runs at the end of execution. For test method test_case_2 (which is part of test_class_1), the setup_class method is called before the test method is fired.
After this is posted, the method-level setup method (that is part of test_class_1) will be executed. The corresponding teardown methods are called in a similar order (i.e. method-level teardown methods are executed first, then class-level teardown methods are executed).
Nose Fixtures Demo
To demonstrate the use of Fixtures in this Python Nose tutorial, an example cross-browser test with two test cases is used:
Test Case – 1
(1) Navigate to URL: Google.com.
(2) Search for "LambdaTest".
(3) Click on the search result titled -LambdaTest: a powerful cross-browser online testing tool
(4) Determine if the title of the newly opened window does not match the expected title
Test Case – 2
(1) Navigate to the URL; Lambdatest GitHub
(2) Select the first two check boxes
(3) Send "happy test in LambdaTest" to the text box with id=sampletodotext
(4) Click the Add button and verify that the text has been added
implement
Python
1 from nose.tools import with_setup
2 from selenium import webdriver
3 import time
4 from time import sleep
5 from selenium.webdriver.common.by import By
6
7 def setup_func:
8 global driver
9print( "setup_func: setUp Method called")
10 driver = webdriver.Chrome
11 driver.maximize_window
12
13 def teardown_func:
14 global driver
15 print( "teardown_func: Teardown Method called")
16 driver.quit
17
18 @with_setup(setup_func, teardown_func)
19 def test_1:
20 global driver
21 print( "test_1: Initiated")
22 driver.get( 'https://www.google.com')
23 title = "Google"
24 assert title == driver.title
25
26 search_text = "LambdaTest"
27 search_box = driver.find_element(By.XPATH, "//input[@name='q']")
28 search_box.send_keys(search_text)
29
30 # Using Sleep is not a good programming practice
31 # Only used here for demonstration purpose
32 time.sleep(5)
33 search_box.submit
34
35 time.sleep(5)
36
37 # Click on the LambdaTest HomePage Link
38 # This test will fail as the titles will not match
39 title = "Most Powerful Cross Browser Testing Tool Online | LambdaTest"
40 lt_link = driver.find_element(By.XPATH, "//h3[.='LambdaTest: Most Powerful Cross Browser Testing Tool Online']")
41 lt_link.click
42
43 time.sleep(10)
44 assert title == driver.title
45 time.sleep(2)
46
47 @with_setup(setup_func, teardown_func)
48 def test_2:
49 global driver
50 print( "test_2: Initiated")
51driver.get( 'https://lambdatest.github.io/sample-todo-app/')
52
53driver.find_element(By.NAME, "li1").click
54driver.find_element(By.NAME, "li2").click
55
56 title = "Sample page - lambdatest.com"
57 assert title == driver.title
58
59 sample_text = "Happy Testing at LambdaTest"
60 email_text_field = driver.find_element(By.ID, "sampletodotext")
61 email_text_field.send_keys(sample_text)
62 time.sleep(5)
63
64 driver.find_element(By.ID, "addbutton").click
65 time.sleep(5)
66
67 assert driver.find_element(By.XPATH, "//span[.='Happy Testing at LambdaTest']").text == sample_text
Swipe left and right to view the complete code
code walkthrough
First, import the with_setup method from the nose.tools module. The setup_func and teardown_func methods are used as Fixture functions implemented at the function level.
Python
1 from nose.tools import with_setup
2 .................................
3
4 def setup_func:
5global driver
6print( "setup_func: setUp Method called")
7driver = webdriver. Chrome
8driver.maximize_window
9
10 def teardown_func:
11 global driver
12 print( "teardown_func: Teardown Method called")
13 driver.quit
Swipe left and right to view the complete code
A Chrome Web Driver instance is started in the setup_func method and its resources are released in the teardown_func method. @with_setupdecorators are used to add setup (i.e. setup_func) and teardown (teardown_func) methods to the corresponding test functions.
Python
1 @with_setup(setup_func, teardown_func)
2 def test_1:
3 ..........................
4 ..........................
5 ..........................
6
7 @with_setup(setup_func, teardown_func)
8 def test_2:
9 ..........................
10 ..........................
11 ..........................
The inspect tool in Chrome is used to find details of necessary web elements.
Selenium Webdriver APIs, such as find_element, send_keys, etc., are used to locate desired web elements and perform desired operations on those elements. In the Python Nose tutorial, the implementation will not be delved into because it is independent of the testing framework used for Selenium Python testing.
implement
The following commands are used to trigger test execution:
Shell
1 nosetests --verbose --nocapture <file-name.py>
Swipe left and right to view the complete code
The following figure is a screenshot of the execution:
Before the test case is executed, the corresponding setup method (i.e. setup_func) is called. Once the execution of the test function is complete, the corresponding teardown method (i.e. teardown_func) is called.
Parametric testing with the Nose framework
The Nose framework (version 1.3.7) does not directly support parameterized tests. The parameterized (formerly Nose parameterized) package is used to perform parameterized tests using Nose. In addition to Nose, the package supports all popular test automation frameworks in Python.
Install the parameterized package by issuing the following command on the terminal:
Shell
1 pip install parameterized
The latest version of the parameterization package is 0.7.4.
Nose parameterized tests on local Selenium grid
The ToDo application will be tested on Lambda Test for this Python Nose tutorial, targeting three different browsers: Firefox, Microsoft Edge, and Chrome. Here is an overview of the test scenarios:
(1) Navigate to the URL
(2) Select the first two check boxes
(3) Send "happy test in Lambda Test" to the text box with id=sampletodotext
(4) Click the Add button and verify that the text has been added
implement
Python
1 # test_math.py
2 from nose.tools import assert_equal
3 from parameterized import parameterized, parameterized_class
4 import unittest
5 from nose.tools import with_setup
6 from selenium import webdriver
7 import time
8 from time import sleep
9 from selenium.webdriver.common.by import By
10
11 def teardown_func:
12 global driver
13 print( "teardown_func: Teardown Method called")
14 driver.quit
15
16 @parameterized([
17 ( "Firefox"),
18 ( "Chrome"),
19 ( "MicrosoftEdge"),
20 ])
21
22 @with_setup(None, teardown_func)
23 def test_to_do_app(browserName):
24 global driver
25
26 if(browserName == "Chrome"):
27 print( "Test on Chrome Browser initiated")
28 driver = webdriver.Chrome
29 elif(browserName == "MicrosoftEdge"):
30 print( "Test on Edge Browser initiated")
31 # Set the Path accordingly
32 driver = webdriver.Edge( "C:\EdgeDriver\MicrosoftWebDriver.exe")
33
elif(browserName == "Firefox"):
34 print( "Test on Firefox initiated")
35 driver = webdriver.Firefox
36 driver.get( 'https://lambdatest.github.io/sample-todo-app/')
37 driver.maximize_window
38
39 driver.find_element(By.NAME, "li1").click
40 driver.find_element(By.NAME, "li2").click
41
42 title = "Sample page - lambdatest.com"
43 assert title == driver.title
44
45 sample_text = "Happy Testing at LambdaTest"
46 email_text_field = driver.find_element(By.ID, "sampletodotext")
47 email_text_field.send_keys(sample_text)
48 time.sleep(5)
49
50 driver.find_element(By.ID, "addbutton").click
51 time.sleep(5)
52
53 assert driver.find_element(By.XPATH, "//span[.='Happy Testing at LambdaTest']").text == sample_text
Swipe left and right to view the complete code
code walkthrough
The parameterized and parameterized_class modules are imported from the parameterized package.
Python
1 from parameterized import parameterized, parameterized_class
Swipe left and right to view the complete code
Function-level fixtures are used, the main difference is that @with_setup decorators will only have teardown methods, because different test browsers use @parameterized decorators passed to test functions.
Python
1 def teardown_func:
2 global driver
3 print( "teardown_func: Teardown Method called")
4 driver.quit
5
6 @parameterized([
7 ( "Firefox"),
8 ( "Chrome"),
9( "MicrosoftEdge"),
10
])
Swipe left and right to view the complete code
The name of the test browser is passed as an argument to the test function (ie test_to_do_app). The test function is executed once per browser combination, and resources used during setup are released in the teardown method (i.e. teardown_func).
Depending on the browser targeted by the Selenium test automation, start the corresponding WebDriver instance.
Python
1 @with_setup(None, teardown_func)
2 ef test_to_do_app(browserName):
3 lobal driver
4
5 f (browserName == "Chrome"):
6 rint( "Test on Chrome Browser initiated")
7iver = webdriver. Chrome
8 lif (browserName == "MicrosoftEdge"):
9 print( "Test on Edge Browser initiated")
10 # Set the Path accordingly
11 driver = webdriver.Edge( "C:\EdgeDriver\MicrosoftWebDriver.exe")
12 lif (browserName == "Firefox"):
13 rint( "Test on Firefox initiated")
14 river = webdriver.Firefox
Swipe left and right to view the complete code
The rest of the implementation is the same, only relevant for Selenium automated testing. Here's a snapshot of the output:
Nose parametric testing on a cloud-based Selenium grid
Selenium test automation on a local Selenium web infrastructure can be a hindrance as scaling the internal infrastructure requires significant investment. This is because the infrastructure must be kept up-to-date with a large number of different browsers, browser versions, and devices.
A more scalable approach to realizing the full potential of Selenium Python testing is to leverage the capabilities of parallelization and remote cloud-based Selenium grid support. LambdaTest is one such cloud-based cross-browser testing platform that enables Selenium test automation across more than 3,000 different browser, operating system, and device combinations.
The effort involved in porting a working test implementation tested on a local Selenium grid to a remote cloud-based Selenium grid is minimal as the code changes are mostly infrastructure related.
In order to start testing on LambdaTest, a configuration file must be created on LambdaTest and note down the username and access key in the configuration file section. A combination of access key and password is used to access the Selenium grid on LambdaTest. LambdaTest Dashboard provides all the details related to the tests executed on the Selenium grid. LambdaTest Capability Generator is used to generate browser and platform capabilities required for Selenium automated testing.
In this Python Nose tutorial, parameterized testing will be demonstrated on LambdaTest. First, execute the test cases used in the previous sections on these browser+OS combinations:
Python
1 @parameterized([
2( "Chrome", "83.0", "Windows 10"),
3( "MicrosoftEdge", "81.0", "macOS High Sierra"),
4 ( "Safari", "12.0", "macOS Mojave"),
5( "Firefox", "76.0", "Windows 10"),
6 ])
implement
Python
1 # test_math.py
2 from nose.tools import assert_equal
3 from parameterized import parameterized, parameterized_class
4 from nose.tools import with_setup
5 from selenium import webdriver
6 import time
7 from time import sleep
8 import urllib3
9 import warnings
10 from selenium.webdriver.common.by import By
11
12 def setup_func:
13 global driver
14 global remote_url
15 print( "setup_func: SetUp Method called")
16 # Details can be sourced from
17 user_name = "user-name"
18 app_key = "pass-key"
19 remote_url = "https://"+ user_name + ":"+ app_key + "@hub.lambdatest.com/wd/hub"
20urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
21
22 def teardown_func:
23 global driver
24 print( "teardown_func: Teardown Method called")
25 driver.quit
26
27 @parameterized([
28 ( "Firefox", "76.0", "Windows 10"),
29 ( "Chrome", "83.0", "Windows 10"),
30 ( "MicrosoftEdge", "81.0", "macOS High Sierra"),
31 ( "Safari", "12.0", "macOS Mojave"),
32 ])
33
34 @with_setup(setup_func, teardown_func)
35 def test_to_do_app(browserName, version, platform):
36 global driver
37 global remote_url
38
39 capabilities = {}
40 # Set the desired capabilities from the supplied parameters
41 capabilities[ "browserName"] = browserName
42 capabilities[ "version"] = version
43 capabilities[ "platform"] = platform
44
45 driver = webdriver.Remote(command_executor = remote_url, desired_capabilities = capabilities)
46 driver.get( 'https://lambdatest.github.io/sample-todo-app/')
47 driver.maximize_window
48
49 driver.find_element(By.NAME, "li1").click
50 driver.find_element(By.NAME, "li2").click
51
52 title = "Sample page - lambdatest.com"
53
assert title == driver.title
54
55 sample_text = "Happy Testing at LambdaTest"
56 email_text_field = driver.find_element(By.ID, "sampletodotext")
57 email_text_field.send_keys(sample_text)
58 time.sleep(5)
59
60 driver.find_element(By.ID, "addbutton").click
61 time.sleep(5)
62
63 assert driver.find_element(By.XPATH, "//span[.='Happy Testing at LambdaTest']").text == sample_text
Swipe left and right to view the complete code
code walkthrough
Since the tests are executed on a cloud-based Selenium grid, credentials consisting of a username and password combination are used to access the LambdaTest grid URL – @hub.lambdatest.com/wd/hub
Python
1 remote_url = "https://"+ user_name + ":"+ app_key + "@hub.lambdatest.com/wd/hub"
Swipe left and right to view the complete code
Remote WebDriver uses the remote URL and browser capabilities generated by the function generator.
Python
1 driver = webdriver.Remote(command_executor = remote_url, desired_capabilities = capabilities)
Swipe left and right to view the complete code
The test case takes three input parameters - browser name, browser version, and platform name. These entries constitute the desired functionality passed as parameters to the WebDriver API.
Python
1 @with_setup(setup_func, teardown_func)
2 def test_to_do_app(browserName, version, platform):
3 .........................
4 .........................
5 capabilities = {}
6 # Set the desired capabilities from the supplied parameters
7 capabilities[ "browserName"] = browserName
8 capabilities[ "version"] = version
9 capabilities[ "platform"] = platform
10
11 driver = webdriver.Remote(command_executor = remote_url, desired_capabilities = capabilities)
12 driver.get( 'https://lambdatest.github.io/sample-todo-app/')
13 .........................
14 .........................
Swipe left and right to view the complete code
The rest of the implementation is self-explanatory, as it uses the relevant Selenium WebDriver APIs to locate the desired web elements and perform relevant operations on them.
The execution screenshot is as follows:
Parallel Testing on Cloud-Based Selenium Grid
Like other popular testing frameworks like Python, Nose also supports parallel testing. nose.plugins and the multiprocess plugin can be used to parallelize test runs across a configurable number of worker processes.
While parallelization in execution speeds up CPU-intensive test runs, it benefits IO-intensive tests because most of the time is spent waiting for data to arrive. The official documentation on Nose has in-depth information related to parallel testing.
In this particular Python Nose tutorial, we will focus on parallel testing on a cloud-based Selenium grid. For use cases related to selenium grids for cross-browser testing, a command line option (-processes) in nosetests can be used to distribute test execution over multiple cores.
When using Nose for Selenium test automation, the following commands are useful to achieve parallelization:
Shell
1 nosetests --process-timeout=<optional-process-timeout> --processes=<num-processes> file-name.py
Swipe left and right to view the complete code
Here is a detailed description of the --processes=NUM option that can be used to parallelize tests using the Nose framework.
While there are significant benefits to be gained using parallel testing on a local Selenium grid, it is multiplied if used on a cloud-based Selenium grid. Therefore, it was decided to demonstrate parallel testing in Nose on a cloud-based Selenium grid in this Python Nose tutorial.
Users on the popular site StackOverflow have been looking to take advantage of parallel testing in Nose, and this part of the Python Nose tutorial will help get started with parallel testing in Nose.
Following are three tests that have to be executed in parallel on LambdaTest's Selenium grid.
Test Case – 1 (Browser – Chrome, Version – 71.0, Platform – Windows10)
(1) Navigate to the URL
(2) Select the first two check boxes
(3) Send "happy test in LambdaTest" to the text box with id=sampletodotext
(4) Click the Add button and verify that the text has been added
Test Case – 2 (Browser – Firefox, Version – 64.0, Platform – Windows10)
(1) Navigate to the URL
(2) The expected title is LambdaTest Cross Browser Testing Blog
(3) Assert whether the title of the opened window does not match the expected title
Test Case – 3 (Browser – Safari, Version – 12.0, Platform – macOS Mojave)
(1) Navigate to the URL
(2) Search for "Lambdatest"
(3) Find the first search result and click the same
(4) Assert whether the title of the opened window does not match the expected title
First, use the LambdaTest function generator to generate the required browser and platform functions. For example, shown below is the functionality required for Test Case 1.
Python
1 ch_caps = {
2 "build": "Nose Testing using Chrome on Windows Environment",
3 "name": "Nose Testing on Chrome using Selenium Grid Environment",
4 "platform": "Windows 10",
5 "browserName": "Chrome",
6 "version": "71.0",
7 "selenium_version": "3.13.0",
8 "chrome.driver": 2.42
9}
Swipe left and right to view the complete code
Repeat the same sequence for the remaining two browser and OS combinations. Three separate test cases were created and the corresponding browser capabilities were used for the test scenarios.
implement
Python
1 # test_math.py
2 import nose
3 from nose.tools import <some p
4 from nose.tools import assert_equal
5 from parameterized import parameterized, parameterized_class
6import unittest
7 import math
8 from nose.tools import with_setup
9 from selenium import webdriver
10 import time
11 from time import sleep
12 import urllib3
13 import warnings
14
15 user_name = "user-name"
16 app_key = "pass-key"
17
18 # @parameterized([
19 # ("Chrome", "83.0", "Windows 10"),
20 # ("MicrosoftEdge", "81.0", "macOS High Sierra"),
21 # ("Safari", "12.0", "macOS Mojave"),
22 # ("Firefox", "76.0", "Windows 7"),
23 #])
24
25 #Set capabilities for testing on Chrome
26 ch_caps = {
27 "build": "Nose Testing using Chrome on Windows Environment",
28 "name": "Nose Testing on Chrome using Selenium Grid Environment",
29 "platform": "Windows 10",
30 "browserName": "Chrome",
31 "version": "71.0",
32 "selenium_version": "3.13.0",
33 "chrome.driver": 2.42
34 }
35
36 #Set capabilities for testing on Firefox
37 ff_caps = {
38 "build": "Nose Testing using Firefox on Windows Environment",
39 "name": "Nose Testing on Firefox using Selenium Grid Environment",
40 "platform": "Windows 10",
41 "browserName": "Firefox",
42 "version": "64.0",
43 }
44
45 #Set capabilities for testing on Safari
46 saf_caps = {
47 "build": "Nose Testing using Safari on macOS Mojave Environment",
48 "name": "Nose Testing on Safari using Selenium Grid Environment",
49 "platform": "macOS Mojave",
50 "browserName": "Safari",
51 "version": "12.0",
52 }
53
54 # multiprocess_can_split = True
55
56 def teardown_func:
57 global driver
58 print( "Inside TearDown")
59 driver.quit
60
61 @with_setup(None, teardown_func)
62 def test_verify_todo_app:
63 global driver
64urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
65 # Details can be sourced from
66 remote_url = "https://"+ user_name + ":"+ app_key + "@hub.lambdatest.com/wd/hub"
67
68 driver = webdriver.Remote(command_executor = remote_url, desired_capabilities = ch_caps)
69 driver.get( 'https://lambdatest.github.io/sample-todo-app/')
70 driver.maximize_window
71
72 driver.find_element_by_name( "li1").click
73 driver.find_element_by_name( "li2").click
74
75 title = "Sample page - lambdatest.com"
76 assert title == driver.title
77
78 sample_text = "Happy Testing at LambdaTest"
79 email_text_field =driver.find_element_by_id( "sampletodotext")
80 email_text_field.send_keys(sample_text)
81 time.sleep(5)
82
83 driver.find_element_by_id( "addbutton").click
84 time.sleep(5)
85
86 assert driver.find_element_by_xpath( "//span[.='Happy Testing at LambdaTest']").text == sample_text
87
88 @with_setup(None, teardown_func)
89 def test_lt_blog:
90 global driver
91urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
92 # Details can be sourced from
93 remote_url = "https://"+ user_name + ":"+ app_key + "@hub.lambdatest.com/wd/hub"
94
95 driver = webdriver.Remote(command_executor = remote_url, desired_capabilities = ff_caps)
96driver.get( 'https://www.lambdatest.com/blog/')
97 driver.maximize_window
98
99 expected_title = "LambdaTest | A Cross Browser Testing Blog"
100 assert expected_title == driver.title
101 time.sleep(5)
102
103 @with_setup(None, teardown_func)
104 def test_verify_google:
105 global driver
106urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
107 # Details can be sourced from
108 remote_url = "https://"+ user_name + ":"+ app_key + "@hub.lambdatest.com/wd/hub"
109
110 driver = webdriver.Remote(command_executor = remote_url, desired_capabilities = saf_caps)
111 driver.get( 'https://www.google.com/')
112 driver.maximize_window
113 title = "Google"
114 assert title == driver.title
115
116 search_text = "LambdaTest"
117 search_box = driver.find_element_by_xpath( "//input[@name='q']")
118 search_box.send_keys(search_text)
119
120 time.sleep(5)
121 search_box.submit
122
123 time.sleep(5)
124
125 # Click on the LambdaTest HomePage Link
126 # This test will fail as the titles will not match
127 title = "Most Powerful Cross Browser Testing Tool Online | LambdaTest"
128 lt_link = driver.find_element_by_xpath( "//h3[.='LambdaTest: Most Powerful Cross Browser Testing Tool Online']")
129 lt_link.click
130
131 time.sleep(10)
132 assert title == driver.title
133 time.sleep(2)
Swipe left and right to view the complete code
code walkthrough
Since the required browser functionality is used in the individual test cases, no setup functionality is required. The teardown function terminates the WebDriver instance.
Python
1 # multiprocess_can_split = True
2 def teardown_func:
3global driver
4print( "Inside TearDown")
5 driver.quit
@with_setupdecorators are used to add a teardown (teardown_func) method to the corresponding test function.
Python
1 @with_setup(None, teardown_func)
2 def test_verify_todo_app:
3 ............
4............
5 ............
6 @with_setup(None, teardown_func)
7 def test_lt_blog:
8 ............
9............
10 ............
11 @with_setup(None, teardown_func)
12 def test_verify_google:
13 ............
14............
15 ............
The core implementation does not need to be changed as the changes are only related to the infrastructure.
implement
The following command is used to execute three test cases in parallel on cloud based Selenium Grid
Shell
1nosetests --process-timeout=60 --processes=3 Nose_Parallel_Test.py
Swipe left and right to view the complete code
The reason for choosing 3 is that the current billing plan allows 5 tests to be executed in parallel. Therefore, all three test cases are executed simultaneously on the platform.
Here is a screenshot of the execution showing three tests running in parallel on the cloud-based Selenium grid:
The test executes successfully on the Selenium grid:
epilogue
In this Python Nose tutorial series, a brief introduction to Nose (version 1.3.7), the testing framework for Selenium Python testing. The framework is an extension to unittest to make testing easier. The main advantage of choosing Nose over unittest is that it removes the requirement for boilerplate code.
It also has a large number of plugins that add support for decorators, fixtures, parameterized tests, and more. These features enhance the usability of the framework.
Hope this article helps people understand and execute selenium python tests using Nose.
Original link:
Get acquainted with technical experts and improve IT skills
Talk about development dreams and expand human resources
Participate in topic discussions and win interactive gifts