Open na-- opened 5 years ago
It seems worth it to also allow other request options (https://docs.k6.io/docs/params-k6http) to be specified globally. It'd be especially useful to be able add cookies or to change the global default timeout...
I agree that it would be useful to be able to set defaults for all (or most) request options. Now I don't think that all of these would also need a cli option. For most it would be enough to be able to specify them in the script.
Being able to set a global timeout would definitely be a good addition.
https://github.com/loadimpact/k6/issues/1865 is a request to be able to specify the Content-Type
header globally, which I'll close in favor of this issue.
In general, it's not certain if we'll implement this issue at all. It's more likely we'll go for a whole new version of the HTTP API where you are able to create multiple HTTP clients, each with different default properties (headers, connection reuse and proxy settings, timeouts, etc.). We've delayed even writing an issue for that new and better HTTP API for probably close to 2 years now, due to the many other things that have had higher priority... :disappointed: So I can't give any ETAs, but it will happen eventually, we're slowly running out of more important things... :sweat_smile:
It will probably be done as an xk6 (https://github.com/k6io/xk6) extension initially, and adopted in the k6 core when it's good enough and stable. If someone wants to take an early stab at it, here is some more info on how extensions are made: https://k6.io/blog/extending-k6-with-xk6
Until then, it's worth pointing out that we already have a pure JavaScript wrapper around k6/http
that does some of the things described in this issue, hosted on https://jslib.k6.io/: https://jslib.k6.io/httpx/0.0.3/index.js
We haven't documented it well yet, and it's still a very early prototype, but the code is short enough to be understandable... You can create something like an HTTP client and set headers and tags that are applied to every HTTP request. We also always accept PRs at https://github.com/k6io/jslib.k6.io/ and https://k6.io/docs/ with improvements :sweat_smile:
I encountered the same problem during the implementation of the "functional.js" library for k6.
It's handy to be able to specify default headers, baseURL, tags and other parameters. I implemented a httpx wrapper around the built-in http library to accomplish this. While I have not documented all the functionality, I think the code is self-explanatory, so anyone who finds this issue can consider using it.
import { test } from 'https://jslib.k6.io/functional/0.0.1/index.js';
import { Httpx } from 'https://jslib.k6.io/httpx/0.0.3/index.js';
import { randomIntBetween, randomItem } from "https://jslib.k6.io/k6-utils/1.0.0/index.js";
export let options = {
thresholds: {
'http_req_duration{name:PublicCrocs}': ['p(90)<200'],
checks: [{threshold: 'rate == 1.00', abortOnFail: true}],
},
};
const USERNAME = `user${randomIntBetween(1, 100000)}@example.com`; // Set your own email;
const PASSWORD = 'superCroc2019';
let session = new Httpx({
baseURL: 'https://test-api.k6.io',
headers: {
'User-Agent': "My custom user agent",
"Content-Type": 'application/x-www-form-urlencoded' // or 'MyDefaultContentType'
},
timeout: 20000 // 20s timeout.
});
export default function testSuite() {
test(`Create a test user ${USERNAME}`, (t) => {
let resp = session.post(`/user/register/`, {
first_name: 'Crocodile',
last_name: 'Owner',
username: USERNAME,
password: PASSWORD,
});
t.expect(resp.status).as("status").toEqual(201)
.and(resp).toHaveValidJson();
})
&&
test(`Authenticate the new user ${USERNAME}`, (t) => {
let resp = session.post(`/auth/token/login/`, {
username: USERNAME,
password: PASSWORD
});
t.expect(resp.status).as("Auth status").toBeBetween(200, 204)
.and(resp).toHaveValidJson()
.and(resp.json('access')).as("auth token").toBeTruthy();
let authToken = resp.json('access');
// set the authorization header on the session for the subsequent requests.
session.addHeader('Authorization', `Bearer ${authToken}`);
})
&&
test('04. Create a new crocodile', (t) => {
let payload = {
name: `Croc Name`,
sex: randomItem(["M", "F"]),
date_of_birth: '2019-01-01',
};
let resp = session.post(`/my/crocodiles/`, payload);
t.expect(resp.status).as("Croc creation status").toEqual(201)
.and(resp).toHaveValidJson();
})
}
Note, I'm defining an http client called session
outside of the default function. All requests that use session
, get default parameters defined in the constructor. Session parameters can also be updated in the default function.
See line
session.addHeader('Authorization', `Bearer ${authToken}`);
which adds a new default header to the existing session. Subsequent requests will get this header by default.
Note: both the functional.js and httpx.js libraries are in active development, so you may want to check https://jslib.k6.io/ to see if there are newer releases.
Where are we with this?
custom headers that should be in every request
Some tests interact with different systems (domains), requiring distinct headers.
Perhaps, it is useful to also allow configuring "global" headers for each specific (sub)domains.
Currently users can specify the
userAgent
that would be used by k6 by default when it makes HTTP requests. I'd be useful if we can generalize that and allow users to specify the default value of any header they want globally. Use cases that I can think of:Accept-Encoding
andAccept-Language
headers are pretty much the same for all requests, if you want your test to look like a browser. It might also make some sense to manually set theConnection
header as well.--user-agent
flag, suggesting instead the usage of--header User-Agent="my-custom-useragent-value"
, to avoid CLI interface clutter