K6 Load Testing - How to run different scenarios at the same time - k6

I have written a simple K6 Load testing script that performs a successful login.
I have written a separate K6 Load testing script that performs an unsuccessful login attempt
They are currently separate scripts that you have to run on their own.
What I want to know is how do you simulate users performing different scenarios in one load test? e.g. valid login, invalid login, logout, any other actions.
Do you put the different scenarios all in one script?

There are two approaches the "old" and the "new" (from v0.27.0) onward.
The old approach is to have a default function that chooses to do one or the other on some condition, for example, each third VU iteration is unsuccessful, the others are successfule ones:
export default function() {
if (__ITER % 3 == 2) {
call_to_unsuccessful_login();
} else {
call_to_successful_login();
}
}
In the above example, you obviously need to define the two functions either in the same script or import them from another
After v0.27.0 and the new execution model, you have multiple scenarios using different executors each execution a different "default" function.
So in this case instead of having one default function which chooses, we can configure different execution plans for the successful and unsuccessful logins and directly call the functions that do them.
export let options = {
"scenarios": {
"successful": {
"executor": "constant-vus".
"vus": 2,
"duration": 1m,
"exec": "call_to_successful_login"
},
"unsuccessful": {
"executor": "constant-vus".
"vus": 1,
"duration": 1m,
"exec": "call_to_unsuccessful_login"
}
}
}
In this case both call... functions need to also be exported in the main script.
You can read more on how to configure scenarios and their different options in the documentation.

Related

How to run Cypress BDD Feature using TAGS in the Terminal without closing the test/browser for each Feature

I have a few feature files in my project and I need to execute only the specific cucumber tags (#Regression) from the feature file using Terminal. I could able to run the feature file using the tags. But the test/Browser window gets closed and open for each feature file. In this case, I have to write a login script in all the feature files to avoid this problem.
Expectation: Test/Browser should not be closed each time and Login should happen only at the beginning of the script execution.
Can someone help me to overcome this problem?
Explanation
That you have to run the login for each Scenario in your Feature respectively is the expected behavior, since each test should be as independent as possible in itself.
In order not to have to add a login step for each Scenario again and again, there are so-called Backgrounds in Cucumber. Backgrounds describe steps that apply as a precondition for all Scenarios in a Feature.
Backgrounds behave like normal Scenarios, so for example you can create a Background in each of your Features with a Given step for the login so that it is automatically executed before each scenario.
Example
Each Feature would receive the following Background, which is then automatically executed once before each Scenario:
#SomeTag
Feature: Some Feature
Background: User is logged in
Given the user is logged in
Scenario: Some first scenario
Given ...
When ...
Then ...
Scenario: Some second scenario
Given ...
When ...
Then ...
The implementation of the step definition is then the same as for steps for your normal Scenarios and can be reused in all Features:
import { defineStep, Given } from 'cypress-cucumber-preprocessor/steps';
Given('the user is logged in', () => {
// logic for login
});
// or more generic using defineStep
defineStep('the user is logged in', () => {
// logic for login
});
Regarding the logic for the login it is often suitable to use Cypress Custom Commands (Example Login for Azure AD)

How to use go's TestMain with terratest?

I would like to use go test and the terratest library for an integration test of a cluster with ~10 different components (pods, services, load balancers, links between components, etc). Tools used to build the infrastructure are terraform, kubernetes, and helm. Building the infrastructure takes approx. 10 minutes, so that I do not want to do it separately for every test. My solution suggests to use the pattern of setting up the test infrastructure in TestMain(*testing.M) and to group tests in test suits like TestAuth(*testing.T), TestMonitoring(*testing.T), etc. Now, I need to call terratest components such as terraform.InitAndApply(*testing.T, terraformOptions) outside a test suite that -- apparently to me-- is not possible.
I tried the following:
func TestMain(m *testing.M) {
setupInfrastructure()
rc = m.Run()
teadDownInfrastructure()
os.Exit(rc)
}
func setupInfrastructure() {
terraformOptions := &terraform.Options{
TerraformDir: testFolder,
EnvVars: map[string]string{
"TF_VAR_cluster_size": 3,
},
}
terraform.InitAndApply(t, terraformOptions) // <-- this is the problem
}
As this is the natural way of setting up a comprehensive test infrastructure, what do I miss?
I saw that all terratest samples (https://github.com/gruntwork-io/terratest/tree/master/test) use one test suite, stages and sub-tests, which I do not want to do as it gives up most of the features from go testing. Is this really the only way to do the job?

Way to determine if within a running scheduled task?

How can I tell, within the graph processing logic, if it's being executed through a Scheduled task rather than through user interaction?
PXProcessing doesn't seem to have much, nor does the records within the AUSchedule table
Reason: If I'm in an interactive session, I want to redirect to multiple screens for the document(s) I've created. In a Scheduled task, I don't want to clutter up the server with these Redirects
Take a look through the code repository at SOShipmentEntry. Search for SOInvoiceEntry and it will get you to the Action function where it creates the invoice. You can see that they call the adapter.MassProcess function to see if it is running in a process or not and throws exceptions, sets info, or errors based on the status.
You can also see the AllowRedirect flag in use.
Here is an example of redirecting to the invoice at the end of a shipment invoice creation:
SOInvoiceEntry ie = PXGraph.CreateInstance<SOInvoiceEntry>();
......
......
if (adapter.AllowRedirect && !adapter.MassProcess && created.Count > 0)
{
using (new PXTimeStampScope(null))
{
ie.Clear();
ie.Document.Current = ie.Document.Search<ARInvoice.docType, ARInvoice.refNbr>(((ARInvoice)created[0]).DocType, ((ARInvoice)created[0]).RefNbr, ((ARInvoice)created[0]).DocType);
throw new PXRedirectRequiredException(ie, "Invoice");
}
}

How to send erlang functions source to riak mapreduce via HTTP?

I'm trying to use Riak's mapreduce via http. his is what i'm sending:
{
"inputs":{
"bucket":"test",
"key_filters":[["matches", ".*"]]
},
"query":[
{
"map":{
"language":"erlang",
"source":"value(RiakObject, _KeyData, _Arg) -> Key = riak_object:key(RiakObject), Count = riak_kv_crdt:value(RiakObject, <<\"riak_kv_pncounter\">>), [ {Key, Count} ]."
}
}
]}
Riak fails with "[worker_startup_failed]", which isn't very informative. Could anyone please help me get this to actually execute the function?
WARNING
Allowing arbitrary Erlang functions via map-reduce is a security risk. Any valid Erlang can be executed, including sending your entire data set offsite or formatting the hard drive.
You have been warned.
However, if you implicitly trust any client that may connect to your cluster, you can allow Erlang source to be passed in a map-reduce request by setting {allow_strfun, true} in the riak_kv section of app.config, (or in the advanced.config if you are using riak.conf).
Once you have allowed passing an Erlang function in a map-reduce phase, you need to pass in a function of the form fun(RiakObject,KeyData,Arg) -> [result] end. Note that this must be an anonymous fun, so fun is a keyword, not a name, and it must end with end.
Your function should handle the case where {error,notfound} is passed as the first argument instead of an object. Simply adding a catch-all clause to the function could accomplish that.
Perhaps something like:
{
"inputs":{
"bucket":"test",
"key_filters":[["matches", ".*"]]
},
"query":[
{
"map":{
"language":"erlang",
"source":"fun(RiakObject, _KeyData, _Arg) ->
Key = riak_object:key(RiakObject),
Count = riak_kv_crdt:value(
RiakObject,
<<\"riak_kv_pncounter\">>),
[ {Key, Count} ];
(_,_,_) -> [{error,0}]
end."
}
}
]}
Allowing the source to be passed in the request is very useful while developing and debugging. For production, you really should put the functions in a dedicated pre-compiled module that you copy to the code path of each node so that the phase spec can specify the module and function by name instead of providing arbitrary code.
{"map":{
"language":"erlang",
"module":"yourprecompiledmodule",
"function":"functionname"}}
You need to enable allow_strfun on all nodes in your cluster. To do so in Riak 2, you will need to use the advanced.config file to add this to the riak_kv configuration:
[
{riak_kv, [
{allow_strfun, true}
]}
].
The other option is to create your own Erlang module by using the compiler shipped with Riak and placing the *.beam file in a well-known location for Riak to find. The basho-patches directory is one such place.
Please see the documentation as well:
advanced.config
Installing custom Erlang code
HTTP MapReduce
Using MapReduce
Advanced MapReduce
MapReduce / curl example

casperjs and a/b testing

i have a signup.js test that automates signing up for my web app (obviously). we're currently a/b testing a new flow that takes you to a different page ('.com/signupa' vs '.com/signupb') and i'm wondering what the best way to reflect this in my test.
options:
use evaluateOrDie and make it die at .com/signupb (this seems dumb)
flesh out test for .com/signupb and make it go that route if it hits that test (is this possible?) something like..
casper.waitForResource("classic.png",
function success() {
this.echo('on the old signup flow ');
<continue with regular signup test>
},
function fail() {
this.test.assertExists("classic.png");
<do something else>
});
any other ideas greatly appreciated!
My preference would be to hide some information in each of your pages, so you can cleanly switch on them. E.g.
<span id="version1"></span>
vs.
<span id="version2"></span>
Then, after submitting the form:
casper.then(function(){
if (this.exists('#version2')) {
testNewSite(this);
} else {
testOldSite(this);
}
});
But detecting on something you already know is only in one of the pages, like the "classic.png" you show in your question, is also fine. (It just feels a little more brittle: the web development team can break your tests by renaming that image, or putting an image with that name in the new version, etc., etc.)

Resources