Hi I have a WebFlowTestCase and is working fine but I ran into a prob when I need to test another flow that is in the same controller ( groovy).
The is what my controller looks like:
class MyController {
def someService
def dateHelper = new DateHelper()
def index = {... }
def myCreateFlow = {
start{}
createCase{}
finishCancel{
}
def myViewFlow = {...}
def myEditFlow = {...}
}
I have managed to successfully create the test for myCreateFlow like this:
class MyControllerTest extends WebFlowTestCase {
def myController = new MyController();
#Override
public Object getFlow() {
// TODO Auto-generated method stub
return myController.myCreateFlow
}
protected void setUp() {
super.setUp()
}
protected void tearDown() {
super.tearDown()
}
void testmyCreateFlow()
{
...
}
}
my question is how about the myEditFlow and myViewFlow? How do I register or use it when the getFlow() returns only the myCreateFlow? Is there I way I can use all of them in one webflowtest with out creating a new webflowtestclass? Or is there a way I can put it inside getflow with some switch/if else method something like:
#Override
public Object getFlow() {
// TODO Auto-generated method stub
if condition
return myController.myCreateFlow
else return myController.myEditFlow
}
coz when i tried creating a testmyEditFlow() I get the error below and I know that it is because the get flow only returns the myCreateFlow. At least that is how I perceive the test error msg.
Cannot find state with id 'myEditFlow' in flow 'test' -- Known state
ids are 'array['start', 'createCase'... 'finishCancel']'
You could register your other flows in a setUp method as follows:
protected void setUp() {
super.setUp()
registerFlow("myController/myEdit", myController.myEditFlow)
registerFlow("myController/myView", myController.myViewFlow)
}
Related
I have 2 Flowables (one which is giving me VelocityNed items, and other which I written to consume items from first one); the thing is I don't know how to make the second one right, since I still not feel sure with RxJava
my Flowable code:
private Flowable<Float> getIAS(Flowable<VelocityNed> velocityNed) {
Flowable<Float> flowable = Flowable.create(emitter->{
velocityNed.subscribeWith(new DisposableSubscriber<VelocityNed>() {
#Override public void onNext(VelocityNed v) {
float valueToEmit = (float)Math.sqrt(Math.pow(v.getDownMS(),2)+Math.pow(v.getEastMS(),2)+Math.pow(v.getNorthMS(),2));
//how to emit this
}
#Override public void onError(Throwable t) {
t.printStackTrace();
}
#Override public void onComplete() {
emitter.onComplete();
this.dispose();
}
});
}, BackpressureStrategy.BUFFER);
return flowable;
}
You don't need to create a Flowable manually just to transform the emissions. You can do originalFlowable.map(element -> { transform element however you want }).
In your case it would be something like:
Flowable<Float> flowable = velocityNed.map(v -> {
(float)Math.sqrt(Math.pow(v.getDownMS(),2)+Math.pow(v.getEastMS(),2)+Math.pow(v.getNorthMS(),2));
})
I have been browsing stackoverflow for some days, trying to find how to re-run a whole test class, and not just an #Test step. Many say that this is not supported with TestNG and IRetryAnalyzer, whereas some have posted workarounds, that don't really work.
Has anyone manage to do it?
And just to clarify the reasons for this, in order to avoid answers that say that is not supported in purpose: TestNG is a tool not only for developers. Meaning that is also used from sw testers for e2e testing. E2e tests can have steps that depend each from the previous one. So yes it's valid to re-run whole test class, rather than simple #Test, which is easily can be done via IRetryAnalyzer.
An example of what I want to achieve would be:
public class DemoTest extends TestBase {
#Test(alwaysRun = true, description = "Do this")
public void testStep_1() {
driver.navigate().to("http://www.stackoverflow.com");
Assert.assertEquals(driver.getCurrentUrl().contains("stackoverflow)"));
}
#Test(alwaysRun = true, dependsOnMethods = "testStep_1", description = "Do that")
public void testStep_2() {
driver.press("button");
Assert.assertEquals(true, driver.elementIsVisible("button"));
}
#Test(alwaysRun = true, dependsOnMethods = "testStep_2", description = "Do something else")
public void testStep_3() {
driver.press("button2");
Assert.assertEquals(true, driver.elementIsVisible("button"));
}
}
Let's say that testStep_2 fails, I want to rerun class DemoTest and not just testStep_2
Okay, I know that you probably want some easy property you can specify in your #BeforeClass or something like that, but we might need to wait for that to be implemented. At least I couldn't find it either.
The following is ugly as hell but I think it does the job, at least in a small scale, it is left to see how it behaves in more complex scenarios. Maybe with more time, this can be improved into something better.
Okay, so I created a Test Class similar to yours:
public class RetryTest extends TestConfig {
public class RetryTest extends TestConfig {
Assertion assertion = new Assertion();
#Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
ignoreMissingDependencies = false)
public void testStep_1() {
}
#Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
dependsOnMethods = "testStep_1",
ignoreMissingDependencies = false)
public void testStep_2() {
if (fail) assertion.fail("This will fail the first time and not the second.");
}
#Test( enabled = true,
groups = { "retryTest" },
retryAnalyzer = TestRetry.class,
dependsOnMethods = "testStep_2",
ignoreMissingDependencies = false)
public void testStep_3() {
}
#Test( enabled = true)
public void testStep_4() {
assertion.fail("This should leave a failure in the end.");
}
}
I have the Listener in the super class just in the case I'd like to extend this to other classes, but you can as well set the listener in your test class.
#Listeners(TestListener.class)
public class TestConfig {
protected static boolean retrySuccessful = false;
protected static boolean fail = true;
}
Three of the 4 methods above have a RetryAnalyzer. I left the testStep_4 without it to make sure that what I'm doing next doesn't mess with the rest of the execution. Said RetryAnalyzer won't actually retry (note that the method returns false), but it will do the following:
public class TestRetry implements IRetryAnalyzer {
public static TestNG retryTestNG = null;
#Override
public boolean retry(ITestResult result) {
Class[] classes = {CreateBookingTest.class};
TestNG retryTestNG = new TestNG();
retryTestNG.setDefaultTestName("RETRY TEST");
retryTestNG.setTestClasses(classes);
retryTestNG.setGroups("retryTest");
retryTestNG.addListener(new RetryAnnotationTransformer());
retryTestNG.addListener(new TestListenerRetry());
retryTestNG.run();
return false;
}
}
This will create an execution inside of your execution. It won't mess with the report, and as soon as it finishes, it will continue with your main execution. But it will "retry" the methods within that group.
Yes, I know, I know. This means that you are going to execute your test suite forever in an eternal loop. That's why the RetryAnnotationTransformer. In it, we will remove the RetryAnalyzer from the second execution of those tests:
public class RetryAnnotationTransformer extends TestConfig implements IAnnotationTransformer {
#SuppressWarnings("rawtypes")
#Override
public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
fail = false; // This is just for debugging. Will make testStep_2 pass in the second run.
annotation.setRetryAnalyzer(null);
}
}
Now we have the last of our problems. Our original test suite knows nothing about that "retry" execution there. This is where it gets really ugly. We need to tell our Reporter what just happened. And this is the part that I encourage you to improve. I'm lacking the time to do something nicer, but if I can, I will edit it at some point.
First, we need to know if the retryTestNG execution was successful. There's probably a million ways to do this better, but for now this works. I set up a listener just for the retrying execution. You can see it in TestRetry above, and it consists of the following:
public class TestListenerRetry extends TestConfig implements ITestListener {
(...)
#Override
public void onFinish(ITestContext context) {
if (context.getFailedTests().size()==0 && context.getSkippedTests().size()==0) {
successful = true;
}
}
}
Now the Listener of the main suite, the one you saw above in the super class TestConfig will see if it the run happened and if it went well and will update the report:
public class TestListener extends TestConfig implements ITestListener , ISuiteListener {
(...)
#Override
public void onFinish(ISuite suite) {
if (TestRetry.retryTestNG != null) {
for (ITestNGMethod iTestNGMethod : suite.getMethodsByGroups().get("retryTest")) {
Collection<ISuiteResult> iSuiteResultList = suite.getResults().values();
for (ISuiteResult iSuiteResult : iSuiteResultList) {
ITestContext iTestContext = iSuiteResult.getTestContext();
List<ITestResult> unsuccessfulMethods = new ArrayList<ITestResult>();
for (ITestResult iTestResult : iTestContext.getFailedTests().getAllResults()) {
if (iTestResult.getMethod().equals(iTestNGMethod)) {
iTestContext.getFailedTests().removeResult(iTestResult);
unsuccessfulMethods.add(iTestResult);
}
}
for (ITestResult iTestResult : iTestContext.getSkippedTests().getAllResults()) {
if (iTestResult.getMethod().equals(iTestNGMethod)) {
iTestContext.getSkippedTests().removeResult(iTestResult);
unsuccessfulMethods.add(iTestResult);
}
}
for (ITestResult iTestResult : unsuccessfulMethods) {
iTestResult.setStatus(1);
iTestContext.getPassedTests().addResult(iTestResult, iTestResult.getMethod());
}
}
}
}
}
}
The report should show now 3 tests passed (as they were retried) and one that failed because it wasn't part of the other 3 tests:
I know it's not what you are looking for, but I help it serves you until they add the functionality to TestNG.
This is a know error when using C# expressions in windows workflow. The article at https://learn.microsoft.com/en-us/dotnet/framework/windows-workflow-foundation/csharp-expressions#CodeWorkflows explains the reason and how to fix it. It all works fine for me in standard workflows, but as soon as I add a custom NativeActivity to the WF, I get that same error again !
Below the code of how I load the XAML workflow and the simple NativeActivity (which is the ONLY activity in the test workflow and inside that activity is a simple assign expression).
Loading and invoking WF via XAML:
`XamlXmlReaderSettings settings = new XamlXmlReaderSettings()
{
LocalAssembly = GetContextAssembly()
};
XamlReader reader = reader = ActivityXamlServices.CreateReader(new XamlXmlReader(fileURL, settings));
ActivityXamlServicesSettings serviceSettings = new ActivityXamlServicesSettings
{
CompileExpressions = true
};
var activity = ActivityXamlServices.Load(reader, serviceSettings);
WorkflowInvoker.Invoke(activity);`
Doing it in code throws same Exception:
Variable<string> foo = new Variable<string>
{
Name = "Foo"
};
Activity activity = new Sequence
{
Variables = { foo },
Activities =
{
new TimeExecuteUntilAborted
{
Activities =
{
new Assign<string>
{
To = new CSharpReference<string>("Foo"),
Value = new CSharpValue<string>("new Random().Next(1, 101).ToString()")
}
}
}
}
};
CompileExpressions(activity);//the method from the article mentioned above
WorkflowInvoker.Invoke(activity);
The Native Activity:
[Designer("System.Activities.Core.Presentation.SequenceDesigner, System.Activities.Core.Presentation")]
public sealed class TimeExecuteUntilAborted : NativeActivity
{
private Sequence innerSequence = new Sequence();
[Browsable(false)]
public Collection<Activity> Activities
{
get
{
return innerSequence.Activities;
}
}
[Browsable(false)]
public Collection<Variable> Variables
{
get
{
return innerSequence.Variables;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.AddImplementationChild(innerSequence);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(innerSequence);
}
}
Your TimeExecutedUntilAborted class seems to be the culprit. I was able to swap in one of my own template NativeActivities instead and your workflow executed fine with the expressions. I'm guessing that your class is causing an issue in the compiler method when it parses your code. I used this doc as an example for my NativeActivity: https://msdn.microsoft.com/en-us/library/system.activities.nativeactivity(v=vs.110).aspx.
Sizzle Finger's answer is no solution but pointed me into the right direction to simply check what is different. It came out that the simple call to the base class method was missing:
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata); // !! This needs to be added
metadata.AddImplementationChild(innerSequence);
}
I am trying to test a basic loginscreen (created using tornadofx) with the testfx framework.
I have added 3 test cases which runs fine but the problem is they use the previous stage rather than creating a new one. I want the testcases to run independently.
I am testing a View() and not an App(). If I use MyMainApp().start(stage) and then MyMainApp().stop(), I get the required behaviour.
But how to do this for Views and Fragments.
Below is the code:
class LoginScreenFeatureTest : ApplicationTest() {
override fun init() {
FxToolkit.registerStage { Stage() }
}
override fun start(stage: Stage) {
LoginScreen().openWindow()
//MyMainApp().start(stage)
}
override fun stop() {
FxToolkit.cleanupStages()
//FxToolkit.toolkitContext().registeredStage.close()
//MyMainApp().stop()
}
#Test fun should_contain_button() {
// expect:
verifyThat("#submitBut", hasText("SUBMIT"))
}
#Test fun should_click_on_button_and_pass_login() {
//init
//Why do I always need to erase text. I want a new stage for every test case.
clickOn("#username").eraseText(10).write("validUser")
clickOn("#password").eraseText(10).write("validPwd")
clickOn("#orgId").eraseText(10).write("validOrg")
// when:
clickOn("#submitBut")
// then:
//verify success
}
#Test fun should_click_on_button_and_fail_login() {
//init
clickOn("#username").eraseText(10).write("anyuser")
clickOn("#password").eraseText(10).write("anypwd")
clickOn("#orgId").eraseText(10).write("anyorg")
// when:
clickOn("#submitBut")
// then:
//verify fail
}
}
You can add property which you can edit at any time at you App() class.
class MyMainApp: App() {
override val primaryView: KClass<out View> = primaryViewMyApp
companion object {
var primaryViewMyApp: KClass<out View> = MyMainAppView::class
}
init {
importStylesheet(<your stylesheet>)
}
override fun start(stage: Stage) {
super.start(stage)
}
override fun stop() {
super.stop()
}
}
and in the test you can than use any view you want to use. I didnt try to implement something for Fragment so far...
override fun init() {
FxToolkit.registerStage { Stage() }
}
override fun start(stage: Stage) {
MyMainApp.primaryViewGoApp = <your view>::class
MyMainApp().start(stage)
}
override fun stop() {
FxToolkit.cleanupStages()
MyMainApp().stop()
}
hi I want to stop further test execution when there is no data in dataprovider. My dataproviders get filled up dynamically on the fly. So i want my tests to stop from execution if there is not data in dataprovider. Below is my code snippet.
package myTest;
import org.testng.Reporter;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class NewTest
{
String str;
#DataProvider
public Object[][] test123()
{
System.out.println(" Filling dataprovider.");
return new Object[][]{};
}
#Factory(dataProvider="test123")
public NewTest(String str)
{
System.out.println("Running through factory.");
this.str=str;
}
#Test
public void test1234()
{
Reporter.log("--->>> running test "+str,true);
}
}
I want that test1234 should not run if dataprovider is empty.
You can try adding another method in different class and add Factory
annotation on that. From this method you can call the constructor of this Test Class in order to execute the tests. Before calling the constructor, check if the argument is correct and you actually want to run the tests for this argument. Now you need to call this Factory class.
<code>
Class NewTestFactory(){
#Factory(dataProvider="test123")
public Object[] executeTests(String str){
Object obj[] = new Object[1];
if (str != null){
obj[0] = new NewTest(str)
}
}
return obj
}
</code>
Simply return an empty 2D array.
Something like:
#DataProvider
public Object[][] test123()
{
Object[][] data= null;
System.out.println(" Filling dataprovider.");
if(someSplCondition) //Returning empty 2D so that test doesn't execute
data = Object[0][0]
else
data = fillTestData()
return data;
}
Also, if you are using maven don't forget to put -DfailIfNoTests=false in mvn command