Using Java DSL TestRunner - How to access variable in my own Java-Code - citrus-framework

I'm using the Java DSL with the TestRunner to define my tests and basically want to have the following steps:
Load a JSON-Structure from a REST-Endpoint with the http-client
Extract the received JSON-Structure into a Citrus variable
Then I would like to manipulate this variable with some Java-Code for some reason - But I can't get it available in my Java-Code.
Basically like this:
http(builder -> builder.client("client").send()
.get("/config").header("Content-Type", "application/json"));
http(builder -> builder.client("client").receive()
.response(HttpStatus.OK).messageType(MessageType.JSON)
.extractFromPayload("$", "myConfig"));
The variable is set:
echo("${myConfig}")
shows the desired output. But how can I get access to that variable to do something with it in pure Java?
I tried this approach:
variable("chgConfig", MyClassABC.myStaticFunctionXZY("${myConfig}");
And I already tried to use a Citrus Function, but I don't know how to call/include it using the Java DSL.
Is there perhaps any way, to get the actual TestContext and hand it over to my Java-Code?
My understanding was, when using the TestRunner, everything is immediately executed and I was thinking: Oh, that's cool, as I can just insert standard Java-Code when needed.

Yeah, I found the solution myself, just reading a second (or maybe a third ) time the documentation.
I have changed my Test-Class like this:
#CitrusTest
#Test #Parameters("context")
public void run(#Optional #CitrusResource TestContext context) {
...
.....
...
MyClassABC.myStaticFunctionXZY(context.getVariable("myConfig"));
This injects me the actual Test-Context and allows me to access & manipulate variables from my Java-Code. Great stuff.

Related

Does NUnit 3.9 support Test Suites?

I am trying to find a way to create custom suites of NUnit tests to target our wide variety of environments. The closest thing I found was this http://nunit.org/docs/2.5.6/suite.html which is exactly what I am looking for. Tying to implement this though, the [Suite] annotation doesnt even seem to exist.. Was this taken away? Is there a better solution now?
The SuiteAttribute was eliminated in NUnit 3. It never got a lot of use as most people simply organize their tests by namespace, which provides the same grouping of tests that the SuiteAttribute used to do.
FUN FACT: "Automatic namespace suites" were once a new cool thing!
If you want the ability to group tests in different ways, across namespace boundaries, you can use categories to do it. It's not as easy of course.
An alternative, if you are using the command-line console runner, is to list the fixtures you want to run in a file and use the --testlist option.
Building off of Charlies post from above - The way I was able to set this up was using the --testlist option.
First create a testlist.txt file and store it somewhere in your solution. Structure the file in such a way so if you have a class like.
namespace NamespaceA
{
class TestGroup
{
[Test]
public void TestOne()
{
}
[Test]
public void TestTwo()
{
}
}
}
the files contents would look like this..
NamespaceA.TestGroup.TestOne
or for both..
NamespaceA.TestGroup
Then just your standard consule runner command
"nunit-console.exe" "path/to/.dll" --testlist="path/to/testlist.txt"
:D)

Getting a scala stacktrace

When my scala-js code throws an error, I'd like to send a sensible stacktrace back to my server to put in the logs. By "sensible stacktrace" I mean something that gives the Scala methods, filenames, and line numbers rather than the transpiled javascript code.
I've made good progress by getting the source map and using the Javascript source-map library (https://github.com/mozilla/source-map) to translate each element of the stacktrace from javascript to the corresponding Scala code.
My issue: I need the column number of the javascript code that threw the error but don't see how to obtain it. Printing a StackTraceElement gives a result similar to
oat.browser.views.query.QueryRunView$.renderParamsTable$1(https://localhost:9443/assets/browser-fastopt.js:34787:188)
I need the "188" at the end of the line but don't see how to get it other than calling toString and parsing the result. Looking at the StackTraceElement code, the column number is a private variable with nothing in the API to access it.
Is there another approach to this that I'm completely overlooking? Anything built into scala-js that converts a javascript stacktrace to a Scala stacktrace?
I subsequently found the StackTraceJS library which does what I needed. I combined a ScalaJS facade for it with a facade for JSNlog to come up with a package that meets my needs pretty well. See jsnlog-facade. It logs to the browser console and/or the server, with Scala stack traces. Demo code included.
There is nothing in the public API to access the column number because this is a Java API, and Scala.js cannot add public members to Java APIs.
To work around this issue in the case of StackTraceElement, we export getColumnNumber(): Int to JavaScript. You can therefore use the following code to retrieve the column number:
def columnNumberOfStackTraceElement(ste: StackTraceElement): Int =
ste.asInstanceOf[js.Dynamic].getColumnNumber().asInstanceOf[Int]
Note that this "feature" is undocumented, and might change without notice in a future major version of Scala.js. If it disappears, it will be replaced by something reliable. In the meantime, the above should get you going.

How can I write a code generator in Ceylon

I want to write a code generator that generates a class based on the meta model of another ceylon class. I want the code generator to run at compile time. What is the best way for me to do this. I could probably accomplish this by writing a plugin for gradle or the ceylon build system but I'm hoping for a simpler solution. Unfortunately, I don't see any support for code generators in ceylon. Also, are there any plans for code generators in ceylon?
I want to write this code generator because I'm thinking about writing a simple web framework for ceylon that look at a class like the following using the meta-model:
controller
shared class Controller() {
shared void doSomething() => print("did it!");
}
I plan for it to be like Spring MVC. This framework would make a restful API from the Controller class that allows someone to write an AJAX call like this:
$http.get("/Controller/doSomething");
I want to make things more convenient, high level, and simple by doing something like GWT. I want to create a code generator that automatically generates a class like this:
shared class RemoteController() {
shared void doSomething() {
$http.get("/Controller/doSomething");
}
}
The RemoteController would be run in a user's browser as javaScript and allow client side ceylon code to do an Ajax call like this:
RemoteController().doSomething();
That would end up calling the Controller().doSomething() on the server so "did it!" would be printed.
AST Transformers have been proposed, but are still in the early design phase. For now, to do compile-time code generation, you’ll have to rig up something of your own.
To actually generate the code, I would recommend use of ceylon.ast and ceylon.formatter. The workflow would roughly be:
analyze source code –
either parse it with ceylon.ast (ceylon.ast.redhat::compileAnyCompilationUnit) and analyze it without typechecking,
or parse it using the compiler, run the typechecker, then convert it to ceylon.ast (ceylon.ast.redhat::anyCompilationUnitToCeylon), keeping the typechecker information using the new update hooks in the very soon upcoming 1.2.0 release
edit the source code AST to add your new code (using a custom ceylon.ast.core::Editor that injects new class definitions into the CompilationUnits), or perhaps create entirely new compilation units if the RemoteController lives in a different module
convert the ceylon.ast AST to a compiler AST and feed it into ceylon.formatter to turn the AST into code again (see here for an example of that)
Alternatively, if you integrate this into your build step, you could skip the ceylon.formatter part of step 3 and instead feed the converted compiler AST into the typechecker and rest of the compiler directly.

How to call a step from another step in Cucumber-JVM

In Cucumber (the ruby version) you can easily call steps from other steps and thus build hierarchical libraries of steps making it easy to write the Gherkin feature specifications in the most generic terms.
However it is not readily apparent how to do this in Cucumber-JVM and I have been unable to find documentation for it.
Let me be clear I am not interested in calling the step implementation function directly because I don't want to have to know what its signature is, nor to change the call every time the implementation changes.
Rather, I want to pass an arbitrary string that will go through the regex matcher and automatically find the matching step and execute it. Just as the engine runs all steps.
simple example of what I would expect syntax to look like to define synonym "logout":
When("user logs out") { () =>
d.executeScript("logout();")
}
When("logout") { () =>
Step("user logs out")
}
This functionality is not supported in Cucumber-JVM. (Note that the Cucumber Backgrounder document you link in your question describes using Steps within Steps as "an anti-pattern")
Essentially, we believe that Cucumber is a collaboration tool and that Gherkin is not a programming language.
You can see a longer discussion of how we arrived at this decision here
To call steps within step definitions, inherit cuke4duke.Steps in java
import cuke4duke.StepMother;
import cuke4duke.Steps;
import cuke4duke.annotation.I18n.EN.When;
public class CallingSteps extends Steps {
public CallingSteps(StepMother stepMother) {
super(stepMother);
}
#When("^I call another step$")
public void iCallAnotherStep() {
Given("it is magic"); // This will call a step defined somewhere else.
}
}
Example:
https://github.com/cucumber-attic/cuke4duke/blob/master/examples/java/src/test/java/simple/CallingSteps.java
Note: cuke4duke support scala as well
Calling steps within steps is a terrible anti-pattern that can easily be replaced by something much simpler.
Instead of one step calling another step, have both steps call the same helper method.
If you apply this pattern with rigour you and up with
step definitions that are all just single calls to helper methods
a suite of helper methods that collectively provide a test-api
The art of elegantly implementing your Cucumber scenarios now becomes a known programming problem as all your functionality is now directly in code in your programming language rather than being in some restrictive construct specific to Cucumber.
You can now
refactor your helper methods to provide cleaner interaces
use parameters to give methods greater power
use naming to give all your calls greater clarity
use a helper method as an entry point to a suite of extra functionality
use delegation to move functionality out of helper methods and into test service objects
...
Providing this separation can be initially challenging if you are not a programmer or not experienced in the particular programming language in use. However once you get past this initial hurdle the code you can and should produce will be much easier to work with than the tangled mess that inevitably occurs with step nesting.
In Cucumber each Step is a Method. That way, you can call other methods in any step that you want.
#When("^click on \"([^\"]*)\"$")
public void clickOn(String arg1) throws Throwable {
driver.findElement(By.linkText(arg1)).click();
}
#Then("^should see the static elements changing$")
public void shouldSeeTheStaticElementsChanging() throws Throwable {
clickOn();
}

How to create a scala class based on user input?

I have a use case where I need to create a class based on user input.
For example, the user input could be : "(Int,fieldname1) : (String,fieldname2) : .. etc"
Then a class has to be created as follows at runtime
Class Some
{
Int fieldname1
String fieldname2
..so..on..
}
Is this something that Scala supports? Any help is really appreciated.
Your scenario doesn't seem to make sense. It's not so much an issue of runtime instantiation (the JVM can certainly do this with reflection). Really, what you're asking is to dynamically generate a class, which is only useful if your code makes use of it later on. But how can your code make use of it later on if you don't know what it looks like? For example, how would your later code know which fields it could reference?
No, not really.
The idea of a class is to define a type that can be checked at compile time. You see, creating it at runtime would somewhat contradict that.
You might want to store the user input in a different way, e.g. a map.
What are you trying to achieve by creating a class at runtime?
I think this makes sense, as long as you are using your "data model" in a generic manner.
Will this approach work here? Depends.
If your data coming from a file that is read at runtime but available at compile time, then you're in luck and type-safety will be maintained. In fact, you will have two options.
Split your project into two:
In the first run, read the file and write the new source
programmatically (as Strings, or better, with Treehugger).
In the second run, compile your generated class with the rest of your project and use it normally.
If #1 is too "manual", then use Macro Annotations. The idea here is that the main sub-project's compile time follows the macro sub-project's runtime. Therefore, if we provide the main sub-project with an "empty" class, members can be added to it dynamically at compile time using data that the macro sees at runtime. - To get started, Modify the macro to read from a file in this example
Else, if you're data are truly only knowable at runtime, then #Rob Starling's suggestion may work for you as it did me. I'll share my attempt if you want to be a guinea pig. For debugging, I've got an App.scala in there that shows how to pass strings to a runtime class generator and access it at runtime with Java reflection, even define a Scala type alias with it. So the question is, will your new dynamic class serve as a type-parameter in Slick, or fail to, as it sometimes does with other libraries?