I've built my pytest class in the following manner:
class Test_Exit_Code(object):
def setup_class(cls):
If 2==2:
# stop execution of the test class
def test_a(self):
assert True==True
As you can see inside the setup_class method i've inserted an IF , what i want to achieve in the if section is that if a certain condition appears to be true instead of the comment i want to return exit code 5 , i.e. no tests were collected .
so far i haven't found any way to do it.
You could try calling pytest.exit(). Also it seems you are missing the classmethod decorator
class Test_Exit_Code:
#classmethod
def setup_class(cls):
If 2==2:
pytest.exit("test exit code setup failed", returncode=5)
pytest.exit
Setup / Teardown
Related
how to parametrize a class with a fixture to make pytest first run entirety of class tests with one fixture return value, then the other. with code smth like this
#pytest.fixture(scope="class",
params=['param1', 'param2']
autouse=True)
def my_fixt(request):
return request.param
class TestMe:
def test_1(self)
...
def test_2(self)
...
def test_3(self)
...
i need tests to run like so:
test1(param1)
test2(param1)
test3(param1)
test1(param2)
test2(param2)
test3(param2)
but if its coded as above it tries to run each test method with both param1 and param2, before proceeding to next method, trying to do everything in a single iteration over the class.
Let's explain my question with an example:
import pytest
#pytest.fixture(scope="session", autouse=True)
def print_session():
print("session fixture")
yield
def setup_function(funtion):
print("function setup")
def test_printer1():
print("test test_printer1")
def test_printer2():
print("test test_printer2")
Currently, I am getting this:
example3.py::test_printer1
session fixture
function setup
test test_printer1
example3.py::test_printer2
function setup
test test_printer2
But, I want to get this:
example3.py::test_printer1
function setup
session fixture
test test_printer1
example3.py::test_printer2
function setup
test test_printer2
Notice that setup_function must be executed prior to every single test case.
¿Is there any way to achieve such an aim? I mean to have a setup_function that gets executed prior to any fixture disregarding its scope on Pytest.
If Pytest is not a requirement you can use unittest to do that, i personally do exactly this in one of my projects.
import unittest
class TestExample(unittest.TestCase):
def setUp(self):
self.foo = 'bar'
def tearDown(self):
self.foo = None
Then you can create all your test cases as methods inside that class and every single one will have the setup function running before it and the teardown after it. Like so:
def test_foo(self):
self.assertTrue(self.foo == 'bar')
I'm executing my selenium script multiple times by using pytest-repeat. i need to capture the iteration number during execution and make use of it.
I explored pytest.mark, pytest.collect & pytest.Collector
class Testone():
#pytest.fixture()
def setup(self):
#pytest.mark.repeat(RowCount)
def test_create_eq(self,setup):
Need to capture the iteration number here.
I think there should be an easier and straightforward way than what I describe below. pytest-repeat has a fixture __pytest_repeat_step_number which I hoped could provide the current step number for the test but it did not.
request.node.name provides the name of the test function generated by pytest_repeat and it has the step number which can be extracted for your purpose.
import pytest
class Testone():
#pytest.fixture()
def setup(self):
pass
#pytest.mark.repeat(4)
def test_create_eq(self,setup,request):
current_step = request.node.name.split('[')[1].split('-')[0] #string form; parse to int, if required
I have a use case where I need to mock a member variable but I want it to return a different value every time it is accessed.
Example;
def run_test():
myClass = MyDumbClass()
for i in range(2):
print(myClass.response)
class MyDumbClass():
def __init__(self):
self.response = None
#pytest.mark.parametrize("responses", [[200,201]])
#patch("blah.MyDumbClass")
def test_stuff(mockMyDumbClass, responses)
run_test()
assert stuff
What I am hoping for here is in the run_test method the first iteration will print 200 then the next will print 201. Is this possible, been looking through unittest and pytest documentation but can't find anything about mocking a member variable in this fashion.
Just started learning pytest and unittest with python3 so forgive me if the style isn't the best.
If you wrap myDumbClass.response in a get function - say get_response() then you can use the side_effect parameter of the mock class.
side_effect sets the return_value of the mocked method to an iterator returning a different value each time you call the mocked method.
For example you can do
def run_test():
myClass = MyDumbClass()
for i in range(2):
print(myClass.get_response())
class MyDumbClass():
def __init__(self):
self.response = None
def get_response(self):
return self.response
#pytest.mark.parametrize("responses", [([200,201])])
def test_stuff( responses):
with mock.patch('blah.MyDumbClass.get_response', side_effect=responses):
run_test()
assert False
Result
----------------------------------- Captured stdout call ------------------------------------------------------------
200
201
Edit
No need to patch via context manager e.g with mock.patch. You can patch via decorator in pretty much the same way. For example this works fine
#patch('blah.MyDumbClass.get_response',side_effect=[200,100])
def test_stuff(mockMyDumbClass):
run_test()
assert False
----------------------------------- Captured stdout call ------------------------------------------------------------
200
201
I have 5 test steps in a test case and i want to write a script assertion for a test step
Like
def groovyUtils = new com.eviware.soapui.support.GroovyUtils( context )
def httpResponseHeaders = context.testCase.testSteps["Step1"].testRequest.response.responseHeaders
def httpStatus = httpResponseHeaders["#status#"]
def httpStatusCode = (httpStatus =~ "[1-5]\\d\\d")[0]
if (httpscode == "500")
I want to re-run the test step named as step 1
I know that testRunner class is not present in Script assertion is there a way to do it with messageExchange variable class
I saw an answer on stack overflow
`messageExchange.modelItem.testStep.testCase.getTestStepByName("Step1").run(context.getTestRunner(),context)`
I tried the code but as soon as i click run SOAP UI hangs and I have to force close the SOAP UI application
To run a test step from script assertion you may use this
import com.eviware.soapui.support.types.StringToObjectMap
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
def Runner = new WsdlTestCaseRunner(messageExchange.modelItem.testStep.testCase, new StringToObjectMap())
yourTestStep= messageExchange.modelItem.testStep.testCase.testSuite.project.testSuites["ScriptLibrary"].testCases["Library"].testSteps["Lib"]
yourTestStep.run(Runner,context)
Your code is fine, except your logic is flawed, because you encounter the error 500 for the first time and then you call the same step again and it fails again with 500 and so on. You would need to get different status, before your Java runs out of memory.
So if you want to do something like that, you have to implement some kind of counter (using TestCase, TestSuite, Project or Global property) to perform this loop only several times and then fail.
Anyway this worked for me:
def utilitiesSuite = messageExchange.modelItem.testStep.testCase
.testSuite.project.getPropertyValue('utilitiesTestSuiteName');
messageExchange.modelItem.testStep.testCase.testSuite.project
.testSuites[utilitiesSuite].testCases["Test Case utility name"]
.run(null, true);
In this case we have all "utilities" = test cases with some often needed functionality in a dedicated test suite and I wanted its name to be possible to set up on Project level, of coures the Test Suite name can be put there directly as for example "Utilities'.
Also i have tried with this:
context.getTestRunner()
As the first parameter in the methor run instead of the null, but it worked only when testing the one requirement, not when running whole test case or test suite.
I let here another example that worked for me.
It's an assertion script, which runs a testStep basing on a response node value.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context );
def holder = groovyUtils.getXmlHolder( "yourTestStep#response" );
def myValue = holder.getNodeValue( "//theNameSpace:yourNode" );
if(myValue == 'whateverYouWant'){
//com.eviware.soapui.support.UISupport.showInfoMessage(myValue);
def Runner = new com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner(
messageExchange.modelItem.testStep.testCase, new com.eviware.soapui.support.types.StringToObjectMap());
def mySteps= messageExchange.modelItem.testStep.testCase.testSuite.project.testSuites["yourTestSuite"].testCases["yourTestCase"].testSteps["yourTestStep"];
mySteps.run(Runner,context);
}