API Testing
TestCafe includes a comprehensive set of server-side API testing tools. You can add dedicated API tests to your test suite, or include API testing methods in existing functional tests.
The inclusion of API tests or checks significantly increases your test coverage, and allows you test your application’s server-side components right alongside its client side.
You can use the t.request
method to do the following:
- Send requests to your application’s web server to prepare the testing environment;
- Send requests to your application’s web server to verify the success of post-test cleanup.
The request
method requires access to the TestController object. You cannot chain this method with other TestController methods.
How API testing works
API tests send HTTP requests to the server and compare the server’s responses to the expected outcome.
Use the request
method to send HTTP requests. Use assertions to verify HTTP responses.
Quick Guide
API tests do not need page access. You can omit the URL when you define the fixture.
fixture`request`;
Declare a new test. Asynchronously call the
request
method from the test body. Save the results to an object.const results = await t.request(`http://localhost:3000/api/data`);
Use assertions to check the object’s properties.
await t .expect(results.status).eql(200) .expect(results.statusText).eql('OK') .expect(results.headers).contains({ 'content-type': 'application/json; charset=utf-8' }) .expect(results.body.data).eql({ name: 'John Hearts', position: 'CTO', });
Send HTTP Requests
The request
method is asynchronous. To send a simple GET
request, pass the target URL to the request
method:
await t.request(`http://localhost:3000/api/data`);
If you want to specify multiple request parameters, store them in an object:
await t.request({url: 'http://example.com', method: 'head'});
Important
The request
method calls trigger your request hooks.
Request Parameters
You can specify the following request parameters:
- The target URL - mandatory
- The HTTP method
- The request body
- URL query parameters
- Receive credentials?
- Basic HTTP authentication credentials
- Request headers
- Request timeout
- Proxy settings
- Response format
Specify the URL
Every HTTP request needs a target URL. The target URL can be either absolute or relative. If you specify a relative URL, TestCafe calculates the absolute URL in relation to the current page.
There are two ways to specify the target URL.
You can pass the URL string directly to the
request
method:await t.request(`http://localhost:3000/api/data`);
Alternatively, use the
url
option:await t.request({ url: 'http://localhost:3000/api/data' });
If you define both, the first argument takes priority:
await t.request(`http://localhost:3000/api/1`, {url: 'http://localhost:3000/api/2'}); // sends a request to /api/1
Specify the HTTP Method
Note
The request
method does not support CORS.
Your requests can use any standard HTTP protocol method. If you don’t specify the HTTP method, the request
method sends a GET
request.
You can specify the HTTP method with the method
property:
await t.request({
url: 'http://localhost:3000/api/data',
method: 'head'
});
Alternatively, you can append select HTTP methods to the request
method itself:
await t.request.head({
url: 'http://localhost:3000/api/data'
});
Request Body
Use the body
option to specify request body.
await t.request.patch({
url: 'http://localhost:3000/api/data',
body: {name: 'Jane Doe', position: 'CTO'}
});
URL Query Parameters
Use the params
option to specify URL query parameters. Make sure your parameters meet the requirements of the URLSearchParams API.
await t.request.patch({
url: 'http://localhost:3000/api/data',
params: {
uid: 503,
auth: true
}
});
Receive Credentials
The withCredentials
option determines whether the response should include credentials such as cookies and authorization headers.
The default value of the withCredentials
option is false
. If you enable the withCredentials
option, TestCafe applies the credentials that it receives to the current page.
Do not enable the withCredentials
option for same-origin requests.
await t.request({
url: 'http://localhost:3000/api/data',
withCredentials: true
});
HTTP Authentication
The auth
option enables Basic HTTP Authentication. It accepts two arguments — the username and the password.
await t.request({
url: 'http://localhost:3000/api/data',
auth: {
username: 'admin',
password: '1234'
}
});
Request Headers
The headers
option specifies request headers.
await t.request({
url: 'http://localhost:3000/api/data',
headers: {
"Accept": "text/html"
}
});
Request Timeout
The timeout
option specifies the timeout value in milliseconds. The method fails if the request does not resolve within the timeout window. The default timeout
value is 25000 ms.
await t.request({
url: 'http://localhost:3000/api/data',
timeout: 40000
});
Proxy Settings
The proxy
option specifies proxy settings.
await t.request({
url: 'http://localhost:3000/api/data',
proxy: {
protocol: 'http',
host: 'http://www.proxy.com',
port: 3200,
auth: {
username: 'proxyUser22',
password: '12345'
};
}
});
Response Format
TestCafe formats the body of the response for easier parsing (see Observe Response Body). To receive raw response data, enable the rawResponse
option:
await t.request({
url: 'http://localhost:3000/api/data',
rawResponse: true
});
The default value of rawResponse
is false
.
Observe HTTP Responses
The request
method returns an object with the following properties:
You can examine the HTTP response in one of two ways:
- Execute the
request
method inside an assertion; - Save the return value of the
request
method.
Execute a request inside an assertion
If you pass the t.request
method to an assertion, the method becomes subject to the Smart Assertion Query Mechanism. If your request fails, TestCafe repeats it within the assertion timeout until the request succeeds.
await t.expect(t.request(`http://localhost:3000/helloworld`).body).contains('Hello World') // true
await t.expect(t.request.post({url: `http://localhost:3000/user`, timeout: 30000}).status).eql(200, 'ok posting', {timeout: 50000}) // true
Save the return value
Alternatively, you can save the return value of the request
method and use assertions later on in the test.
const response = await t.request(`http://localhost:3000/helloworld`);
console.log(response.body) // 'Hello World'
t.expect(response.body).contains('Hello World') // true
If you only need to examine a single property, you can append the name of the property to the request method:
const responseBody = await t.request(`http://localhost:3000/helloworld`).body;
console.log(responseBody) // 'Hello World'
t.expect(responseBody).contains('Hello World') // true
Response Status
The status
property contains the status code of the HTTP response.
const response= await t.request(`http://localhost:3000/helloworld`);
console.log(response.status) // '200'
Response Status Text
The statusText
property contains the status text of the HTTP response.
const response= await t.request(`http://localhost:3000/helloworld`);
console.log(response.statusText) // 'OK'
Response Headers
The headers
property contains the headers of the HTTP response.
const response= await t.request(`http://localhost:3000/helloworld`);
console.log(response.headers) // "{'content-type': 'application/json; charset=utf-8'}"
Response Body
The responseBody
property contains the body of the response. TestCafe formats the property for easier parsing.
- If the
content-type
of the response istext/html
ortext/plain
, the response body is aString
.const responseBody = await t.request(`http://localhost:3000/helloworld`).body; console.log(responseBody) // 'Hello World'
- If the
content-type
of the response isapplication/json
, theresponseBody
property is anObject
.const responseBody = await t.request(`http://localhost:3000/json/api`).body; console.log(responseBody) // '{"message": "Hello World"}'
- If the
content-type
of the response is neitherapplication/json
nortext/plain
, theresponseBody
property becomes aBuffer
.const responseBody = await t.request(`http://localhost:3000/json/api`).body; console.log(responseBody) // '<Buffer 61 62 63 ... >'
If you enable the rawResponse option, TestCafe does not format the responseBody
property.
Limitations
- The
request
method does not support CORS. - The
request
method is a server-side method. TestCafe executes it within a Node.JS environment. You cannot debug it in the browser’s Network tab.