F# Computation Expressions for NBomber API
Package
Description
Status
NBomber.FSharp
CE for test runners, scenarios and steps
NBomber.FSharp.Http
CE for http calls steps, similar to NBomber.Plugins.Http
NBomber.FSharp.Hopac
Hopac support for the above, depends on both
Fluent API Computation Expression
Scenario.create " test" [ step]
|> Scenario.withWarmUp ( seconds 10 )
|> Scenario.withLoadSimulations [
KeepConstant( copies = copiesCount, during = seconds 2 )
]
scenario " test" {
warmUp ( seconds 10 )
load [
KeepConstant( copies = copiesCount, during = seconds 2 )
]
init ( fun _ -> Task.FromResult())
clean ( fun _ -> Task.FromResult())
steps [ myStep]
// or if just one step
myStep
}
The overloads of step
's custom operation execute
accepts a function taking a step context and returning either Response
or unit
directly or wrapped in a task
, async
or even in a Hopac job
Fluent API Computation Expression
Step.create( " step name" ,
myWebsocketPool,
myGuidFeed,
( fun ctx -> task {
let doSomethingWithSocket ( _ : Guid ) ( _ : ClientWebSocket ) =
" "
ctx.Logger.Information( " Can take feed and client {Ret}" ,
takeBoth ctx.FeedItem ctx.Client)
return Response.Ok()
}), true )
step " step name" {
dataFeed myGuidFeed
myWebsocketPool
execute ( fun ctx ->
let doSomethingWithSocket ( _ : Guid ) ( _ : ClientWebSocket ) =
" "
ctx.Logger.Information( " Can take feed and client {Ret}" ,
takeBoth ctx.FeedItem ctx.Client) )
doNotTrack
}
Simplified construction of clients. Notable differences are:
connect
and disconnect
functions are more tolerant for missing type signatures and arguments
no need for cancellationToken
argument if it is not used in connect
or disconnect
functions
disconnect
can be omitted completely, if the type of created connection implements IDisposable
or can be just disposed.
count
of connections can be omitted too, it defaults to 1
even less verbose compared to the C# API
Fluent API Computation Expression
let clientFactory =
ClientFactory.create(
name = " db connections" ,
initClient = ( fun i ctx -> task {
let c = new NpgsqlConnection( connectionString)
do ! c.OpenAsync( ctx.CancellationToken)
return c
}),
disposeClient = ( fun ( c : NpgsqlConnection , ctx ) -> c.CloseAsync( ctx.CancellationToken)),
clientCount = 100 )
let clientFactory =
clients " db connections" {
count 100
connect( fun i ctx -> task {
let c = new NpgsqlConnection( connectionString)
do ! c.OpenAsync( ctx.CancellationToken)
return c
})
disconnect( fun c ctx -> c.CloseAsync( ctx.CancellationToken))
}
Imagine you need just a html report. Then it is as short as
Fluent API Computation Expression
NBomberRunner.withReportFormats [
ReportFormat.Csv
ReportFormat.Txt
ReportFormat.Md
ReportFormat.Html
]
|> NBomberRunner.withReportingSinks
[ influxdbSink
customFormatSink ]
( seconds 10 )
|> NBomberRunner.withReportFolder " reportsFolder"
|> NBomberRunner.withReportFileName " reportFile"
// or if none
|> NBomberRunner.withoutReports
.. .
testSuite " Suite name" {
report {
csv
text
markdown
html
sink influxdbSink
sink customFormatSink
interval ( seconds 10 )
folderName " reportsFolder"
fileName " reportFile"
}
// or if none
noReports
.. .
}
Other runner configuration
Fluent API Computation Expression
NBomberRunner.registerScenarios []
|> NBomberRunner.withTestName " Test name"
|> NBomberRunner.withTestSuite " Suite name"
|> NBomberRunner.withoutReports
|> NBomberRunner.disableHintsAnalyzer
|> NBomberRunner.loadConfig " loadTestConfig.json"
|> NBomberRunner.loadInfraConfig " infrastructureConfig.json"
|> NBomberRunner.withWorkerPlugins []
|> NBomberRunner.withApplicationType ApplicationType.Console
// |> NBomberRunner.runWithArgs args
|> NBomberRunner.run
|> evaluateStatsFunction
testSuite " Suite name" {
testName " Test name"
noReports
noHintsAnalyzer
scenarios scenarioBuilderTest
config " loadTestConfig.json"
infraConfig " infrastructureConfig.json"
plugins [ (* plugins list*) ]
runConsole
// runAsProcess
// runWithArgs args
// runWithExitCode
}