I have written a feature test in Behave Python Selenium. When i run the test it throws the error ImportError No module named pages. I think it cannot find my classes in the pages directory. homepage.py, searchpage.py
Is my imports incorrect? How can i resolve this issue?
The full error is:
> log
Traceback (most recent call last):
File "C:\Python27\lib\runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "C:\Python27\lib\runpy.py", line 72, in _run_code
exec code in run_globals
File "c:\Python27\Scripts\behave.exe\__main__.py", line 9, in <module>
File "C:\Python27\lib\site-packages\behave\__main__.py", line 109, in main
failed = runner.run()
File "C:\Python27\lib\site-packages\behave\runner.py", line 672, in run
return self.run_with_paths()
File "C:\Python27\lib\site-packages\behave\runner.py", line 678, in run_with_pat
self.load_step_definitions()
File "C:\Python27\lib\site-packages\behave\runner.py", line 658, in load_step_de
exec_file(os.path.join(path, name), step_module_globals)
File "C:\Python27\lib\site-packages\behave\runner.py", line 304, in exec_file
exec(code, globals, locals)
File "steps\steps.py", line 5, in <module>
from pages import homepage
ImportError: No module named pages
My code is as follows:
features\steps\steps.py
from behave import given, when, then
from pages import homepage
from pages import searchpage
@given ('we are on the homepage')
def step(context):
context.browser.get('http://localhost:8080/test')
@when ('we enter "{product}" in the search field')
def step(context, product):
home_page = homepage.HomePage(context)
home_page.enter_product_in_search_field(product, context)
@when ('And we click the search button')
def step(context, home_page):
searchPage_results = home_page.click_search_button(context)
@then ('the list of products are displayed')
def step(context, searchPage):
searchPage.search_products_results(context)
features\environment.py
import logging
from selenium import webdriver
def before_all(context):
selenium_logger = logging.getLogger(
'selenium.webdriver.remote.remote_connection')
selenium_logger.setLevel(logging.WARN)
context.browser = webdriver.Firefox()
context.browser.get('http://localhost:8080/test')
context.browser.implicitly_wait(3)
def after_all(context):
context.browser.quit()
pages\homepage.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from searchpage import SearchPage
class HomePage(object):
def __init__(self, context):
context = context
def enter_product_in_search_field(self, product, context):
search_field = context.browser.find_element(By.ID, 'search_field')
search_field.send_keys(product)
return self
def click_search_button(self, context):
search_button = context.find_element(By.ID, 'search_button_home_page').click()
return SearchPage(context)
pages\searchpage.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
class SearchPage():
def __init__(self, context):
context = context
def search_products_results(self, context):
wait = WebDriverWait(context.browser, 60)
divs = wait.until(EC.presence_of_all_elements_located((By.XPATH, '//div/a/h2')))
for i in divs:
print i.text
return self
My directory structure is as follows:
E:\selenium_test\features\steps\steps.py
E:\selenium_test\features\environment.py
E:\selenium_test\features\search.feature
E:\selenium_test\features\__init__.py
E:\selenium_test\pages\homepage.py
E:\selenium_test\pages\searchpage.py
E:\selenium_test\pages\__init__.py
Thanks, Riaz
Preferred
Move pages under feature/steps. Add init file. Then import just works
Harder
Update sys.path to include the location of 'pages'. You can do this from environment.py or steps.py itself
Fiddly
import imp
myPkg = imp.load_source('module.name', '/path/to/pages/file.py')
Just to know:
export PYTHONPATH=$PYTHONPATH:/abs/path/to/pages. Not recommended though.
Illustration:
.
├── anotherpages
│ ├── __init__.py
│ └── third.py
├── features
│ ├── __init__.py
│ └── steps
│ ├── __init__.py
│ ├── pages
│ │ ├── first.py
│ │ └── __init__.py
│ └── steps.py
└── outpages
├── __init__.py
└── second.py
$ cat features/steps/steps.py
#Preferred
from pages.first import inside_hello
inside_hello()
#Harder
import sys
import os
path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))
if not path in sys.path:
sys.path.insert(1, path)
del path
from outpages.second import outside_hello
outside_hello()
#Fiddly
import imp
third = imp.load_source('third', '/path/to/anotherpages/third.py')
from third import another_hello
another_hello()
$ python features/steps/steps.py
Hello from inside
Hello from outer world
Hello from another outer world
$ cd features/steps/
~features/steps$ python steps.py
Hello from inside
Hello from outer world
Hello from another outer world