Pytest - 2 pytest tests, one should pass one should fail - selenium

I have an assignment which asks to do a pytest test and :
· Test should PASS if the string “ Right-click in the box below to see one called 'the-internet' “ found on page.
· Another Test should FAIL if string “Alibaba” is not found on the same page.
my code :
import pytest
def test_text1():
text1 = "Right-click in the box below to see one called 'the-internet'"
if text1 in driver.page_source:
assert text1 in driver.page_source
def test_text2():
text2 = "Alibaba"
if text2 in driver.page_source:
assert text2 in driver.page_source
I'm trying to write a python script and do the pytest test with the Pycharm terminal, and the two tests pass, although the first one should pass and the second should fail.
Do you have any idea how can I solve this? Thanks!

There is no need for an if statement in an assert:
import pytest
def test_text1():
text1 = "Right-click in the box below to see one called 'the-internet'"
assert text1 in driver.page_source
def test_text2():
text2 = "Alibaba"
assert text2 in driver.page_source
You can improve that further by using parametrize:
#pytest.mark.parametrize("text",
["Right-click in the box below to see one called 'the-internet'",
"Alibaba"]
)
test_contains_text(text, driver):
assert text in driver.page_source

Related

Robot framework: running test cases in batch makes them fail, while running a single test case works

I have 22 Robot framework test cases in a folder. All the test cases work perfectly if run individually.
If I try to run them all together, with the command robot . (from the TestCases directory) most of them fail.
The ones that fail make use of a python script to get the performance log of the webpage, with the following code:
d['goog:loggingPrefs'] = {'performance': 'ALL'}
the error I get is:
InvalidArgumentException: Message: invalid argument: log type 'performance' not found
the strange thing is that this happens only when I run all test cases together. Otherwise, error does not appear and log is retrieved correctly.
How can I fix this so the test cases work also when run in batch?
This is the file structure:
Each ROBOT file contains only 1 test case. In the driver.py the custom keywords are defined and called at the beginning of each TC with:
*** Settings ***
Library SeleniumLibrary
Library driver.py
*** Variables ***
*** Keywords ***
Get Logs2
[Arguments] ${arg1}
Get Chrome Browser Logging Capability
Find String
the code that throws the error is in the file "driver.py":
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
def get_chrome_browser_logging_capability():
d = DesiredCapabilities.CHROME
d['goog:loggingPrefs'] = {'browser': 'ALL'}
d['goog:loggingPrefs'] = {'performance': 'ALL'}
return d
def get_logs2(driver):
f = open("demofile2.txt", "w")
a = driver.get_log('performance')
for entry in a:
f.write(str(entry))
f.write('\n')
f.close()
def find_string(mystring):
f = open("demofile2.txt", "r")
for x in f:
for element in mystring:
if element in x:
print("found")
return True
f.close()

Python unit tests for Foundry's transforms?

I would like to set up tests on my transforms into Foundry, passing test inputs and checking that the output is the expected one. Is it possible to call a transform with dummy datasets (.csv file in the repo) or should I create functions inside the transform to be called by the tests (data created in code)?
If you check your platform documentation under Code Repositories -> Python Transforms -> Python Unit Tests, you'll find quite a few resources there that will be helpful.
The sections on writing and running tests in particular is what you're looking for.
// START DOCUMENTATION
Writing a Test
Full documentation can be found at https://docs.pytest.org
Pytest finds tests in any Python file that begins with test_.
It is recommended to put all your tests into a test package under the src directory of your project.
Tests are simply Python functions that are also named with the test_ prefix and assertions are made using Python’s assert statement.
PyTest will also run tests written using Python’s builtin unittest module.
For example, in transforms-python/src/test/test_increment.py a simple test would look like this:
def increment(num):
return num + 1
def test_increment():
assert increment(3) == 5
Running this test will cause checks to fail with a message that looks like this:
============================= test session starts =============================
collected 1 item
test_increment.py F [100%]
================================== FAILURES ===================================
_______________________________ test_increment ________________________________
def test_increment():
> assert increment(3) == 5
E assert 4 == 5
E + where 4 = increment(3)
test_increment.py:5: AssertionError
========================== 1 failed in 0.08 seconds ===========================
Testing with PySpark
PyTest fixtures are a powerful feature that enables injecting values into test functions simply by adding a parameter of the same name. This feature is used to provide a spark_session fixture for use in your test functions. For example:
def test_dataframe(spark_session):
df = spark_session.createDataFrame([['a', 1], ['b', 2]], ['letter', 'number'])
assert df.schema.names == ['letter', 'number']
// END DOCUMENTATION
If you don't want to specify your schemas in code, you can also read in a file in your repository by following the instructions in documentation under How To -> Read file in Python repository
// START DOCUMENTATION
Read file in Python repository
You can read other files from your repository into the transform context. This might be useful in setting parameters for your transform code to reference.
To start, In your python repository edit setup.py:
setup(
name=os.environ['PKG_NAME'],
# ...
package_data={
'': ['*.yaml', '*.csv']
}
)
This tells python to bundle the yaml and csv files into the package. Then place a config file (for example config.yaml, but can be also csv or txt) next to your python transform (e.g. read_yml.py see below):
- name: tbl1
primaryKey:
- col1
- col2
update:
- column: col3
with: 'XXX'
You can read it in your transform read_yml.py with the code below:
from transforms.api import transform_df, Input, Output
from pkg_resources import resource_stream
import yaml
import json
#transform_df(
Output("/Demo/read_yml")
)
def my_compute_function(ctx):
stream = resource_stream(__name__, "config.yaml")
docs = yaml.load(stream)
return ctx.spark_session.createDataFrame([{'result': json.dumps(docs)}])
So your project structure would be:
some_folder
config.yaml
read_yml.py
This will output in your dataset a single row with one column "result" with content:
[{"primaryKey": ["col1", "col2"], "update": [{"column": "col3", "with": "XXX"}], "name": "tbl1"}]
// END DOCUMENTATION

using scrapy creating a spider and unable to store data to csv

I'm pretty new to scrapy, here I created a spider using the amazon URL unable to get the output to the csv.
Here is my code:
import scrapy
class AmazonMotoMobilesSpider(scrapy.Spider):
name = "amazon"
start_urls = ['https://www.amazon.in/Samsung-Mobiles/b/ref=amb_link_47?ie=UTF8&node=4363159031&pf_rd_m=A1VBAL9TL5WCBF&pf_rd_s=merchandised-search-leftnav&pf_rd_r=NGA52N9RAWY1W103MPZX&pf_rd_r=NGA52N9RAWY1W103MPZX&pf_rd_t=101&pf_rd_p=1ce3e975-c6e8-479a-8485-2e490b9f58a9&pf_rd_p=1ce3e975-c6e8-479a-8485-2e490b9f58a9&pf_rd_i=1389401031',]
def parse(self,response):
product_name = response.xpath('//h2[contains(#class,"a-size-base s-inline s-access-title a-text-normal")]/text()').extract()
product_price = response.xpath('//span[contains(#class,"a-size-base a-color-price s-price a-text-bold")]/text()').extract()
yield {'product_name'product_name,'product_price': product_price}
My shell is showing this result:
len(response.xpath('//h2[contains(#class,"a-size-base s-inline s-access-tit
le a-text-normal")]/text()'))
24
do I need to change any settings ?
To generate results in CSV you need to run the crawler with a output option
scrapy crawl -o results.csv spidername
Only when you activate a output the results are sent to the file. Else they will processed by your piplelines. If you are not saving them anywhere through pipeline then they will be just on terminal's console logs
I think Its because your yield has some syntax errors in the dictionary.
Change this
yield {'product_name'product_name,'product_price': product_price}
to
yield {'product_name':product_name,'product_price': product_price}

User input produces blank file with no result

I am playing around with Selenium to get screenshots of websites to view them safely.
The original code I found and tweaked was like this and works.
from selenium import webdriver
br = webdriver.PhantomJS()
br.get('http://www.google.com')
br.save_screenshot('screenshot.png')
br.quit
It gives you a screenshot of the website
I wanted to get user input so that I did not have the VI the file overtime I need a screenshot of a URL this is what I changed the code too.
#!/usr/bin/python
import re
import sys
from selenium import webdriver
br = webdriver.PhantomJS()
br.get_user_input =raw_input('Enter URL:')
br.save_screenshot('screenshot.png')
br.quit
Now it ask for the URL and you input it in the program runs and finishes and even creates the screenshot.png file but its blank
try to use a chrome canary (if you need headless browser). you don't have to use a selenium.
make_screen = '''#!/usr/bin/env bash
test -f ./chrome-linux/chrome && echo "chrome exists" || unzip chrome-linux.zip
./chrome-linux/chrome --headless --disable-gpu --virtual-time-budget=7000 --hide-scrollbars --screenshot=dir/screens/{screen_prod}.png --window-size=1200,2000 {link_prod}'''.format(screen_prod = screen_prod, link_prod = link_prod)
Here is the Answer to your Question:
There is a small bug in your code. You havn't called the get() method with your WebDriver instance br.
As a solution, (to avoid Law of Demeter) I have broken up that line in to two. Took the url from the user as an input in the first line. In the next line passed the url as an argument to get() method. Next it takes a proper snapshot and saves it within Screenshots sub-directory. Here is the working code block :
from selenium import webdriver
br = webdriver.PhantomJS(executable_path="C:\\Utility\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe")
user_input = input('Enter URL : ')
br.get(str(user_input))
br.save_screenshot('./Screenshots/my_next_screenshot.png')
br.quit
The output on my console is:
Enter URL : http://google.com
Process finished with exit code 0
Let me know if this Answers your Question.

Running external selenium script from Groovy[SOAPUI]

I see online that the way to run a simple python file from groovy is:
def cmdArray2 = ["python", "/Users/test/temp/hello.py"]
def cmd2 = cmdArray2.execute()
cmd2.waitForOrKill(1000)
log.info cmd2.text
If hello.py contains - Print "Hello". It seems to work fine
But when I try to run a .py file containing the below Selenium code nothing happens.
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.PhantomJS(executable_path=r'C:\phantomjs\bin\phantomjs.exe')
driver.get("http://www.google.com") # Load page
# 1 & 2
title = driver.title
print title, len(title)
driver.quit()
Any help would be appreciated.
FYI - I have tried using all the browsers including headless browsers but no luck.
Also, I am able to run the selenium script fine from the command line. But when I run from the SOAPUI, I get no errors, the script runs and I do not see anything in the log
Most likely you do not see any errors from your python script because they are printed to stderr not stdout (as you expected when called cmd2.text). Try this groovy script to check error messages from python script stderr
def cmdArray2 = ["python", "/Users/test/temp/hello.py"]
def process = new ProcessBuilder(cmdArray2).redirectErrorStream(true).start()
process.inputStream.eachLine {
log.warn(it)
}
process.waitFor()
return process.exitValue()
Another thing you might want to try is using selenium directly from groovy without calling external python script.