A powerful .NET source generator that automatically converts .http files into fully functional C# test code. This tool bridges the gap between API testing in IDEs (like Visual Studio Code with the REST Client extension) and automated testing in your .NET projects.
- Automatic Test Generation: Transform
.httpfiles into xUnit or TUnit test code at compile time - Rich HTTP Support: Parse GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, and TRACE methods
- Header Processing: Full support for HTTP headers including custom headers
- Request Bodies: Support for JSON, XML, and text request bodies
- Response Assertions: Validate expected status codes and response headers
- Multiple Test Frameworks: Generate tests for xUnit and TUnit
- Source Generator: Zero-runtime overhead with compile-time code generation
- IDE Integration: Works seamlessly with existing
.httpfiles in your IDE
<PackageReference Include="HttpTestGen.XunitGenerator" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference><PackageReference Include="HttpTestGen.TUnitGenerator" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>Create a .http file in your test project with HTTP requests:
# Simple GET request
GET https://api.example.com/users
# GET request with headers
GET https://api.example.com/users/123
Accept: application/json
Authorization: Bearer your-token-here
# POST request with JSON body
POST https://api.example.com/users
Content-Type: application/json
{
"name": "John Doe",
"email": "[email protected]"
}
# Request with expected status code
GET https://api.example.com/nonexistent
EXPECTED_RESPONSE_STATUS 404
# Request with expected response headers
GET https://api.example.com/data
EXPECTED_RESPONSE_HEADER content-type: application/json
EXPECTED_RESPONSE_HEADER x-custom-header: custom-valueThe source generator automatically creates test methods from your .http files. For example, the above .http file would generate:
public class ApiTestsXunitTests
{
[Xunit.Fact]
public async Task get_api_example_com_0()
{
var sut = new System.Net.Http.HttpClient();
var response = await sut.GetAsync("https://api.example.com/users");
Xunit.Assert.True(response.IsSuccessStatusCode);
}
[Xunit.Fact]
public async Task get_api_example_com_1()
{
var sut = new System.Net.Http.HttpClient();
var response = await sut.GetAsync("https://api.example.com/users/123");
Xunit.Assert.True(response.IsSuccessStatusCode);
}
[Xunit.Fact]
public async Task post_api_example_com_2()
{
var sut = new System.Net.Http.HttpClient();
var response = await sut.PostAsync("https://api.example.com/users");
Xunit.Assert.True(response.IsSuccessStatusCode);
}
[Xunit.Fact]
public async Task get_api_example_com_3()
{
var sut = new System.Net.Http.HttpClient();
var response = await sut.GetAsync("https://api.example.com/nonexistent");
Xunit.Assert.Equal(404, (int)response.StatusCode);
}
[Xunit.Fact]
public async Task get_api_example_com_4()
{
var sut = new System.Net.Http.HttpClient();
var response = await sut.GetAsync("https://api.example.com/data");
Xunit.Assert.True(response.IsSuccessStatusCode);
Xunit.Assert.True(response.Headers.GetValues("content-type").Contains("application/json"));
Xunit.Assert.True(response.Headers.GetValues("x-custom-header").Contains("custom-value"));
}
}GET- Retrieve dataPOST- Create new resourcesPUT- Update existing resourcesPATCH- Partial updatesDELETE- Remove resourcesHEAD- Retrieve headers onlyOPTIONS- Check available methodsTRACE- Diagnostic trace
GET https://api.example.com/notfound
EXPECTED_RESPONSE_STATUS 404GET https://api.example.com/api/data
EXPECTED_RESPONSE_HEADER content-type: application/json
EXPECTED_RESPONSE_HEADER cache-control: no-cache- Add the NuGet package to your test project
- Create
.httpfiles in your test project - Build your project - tests are generated automatically
- Run tests using your preferred test runner
MyProject.Tests/
βββ MyProject.Tests.csproj
βββ api-tests.http
βββ user-tests.http
βββ integration-tests.http
The source generator will create corresponding test classes:
api-tests.httpβApiTestsXunitTestsorApiTestsTests(TUnit)user-tests.httpβUserTestsXunitTestsorUserTestsTests(TUnit)integration-tests.httpβIntegrationTestsXunitTestsorIntegrationTestsTests(TUnit)
Use # for comments in your .http files:
# This is a comment
GET https://api.example.com/users
# Test user creation
POST https://api.example.com/users
Content-Type: application/json
{
"name": "Test User"
}Separate multiple requests with blank lines or comments:
GET https://api.example.com/users
# Separator comment
GET https://api.example.com/posts
#
GET https://api.example.com/commentsSupport for various content types:
# JSON body
POST https://api.example.com/data
Content-Type: application/json
{
"key": "value"
}
# XML body
POST https://api.example.com/data
Content-Type: application/xml
<root>
<item>value</item>
</root>
# Plain text body
POST https://api.example.com/data
Content-Type: text/plain
This is plain text content- Design your API using
.httpfiles in your IDE - Test manually using REST Client extensions
- Add assertions for expected behavior
- Build project to generate automated tests
- Run tests in CI/CD pipeline
- Organize by feature: Create separate
.httpfiles for different API endpoints or features - Use descriptive comments: Document what each request tests
- Add assertions: Always include expected status codes and important headers
- Environment variables: Use your IDE's environment variable support for different environments
- Version control: Commit your
.httpfiles alongside your code
Generated test method names follow the pattern: {method}_{hostname}_{index}
Examples:
GET https://api.example.com/usersβget_api_example_com_0POST https://localhost:5000/api/dataβpost_localhost_1DELETE https://my-api.azurewebsites.net/items/123βdelete_my_api_azurewebsites_net_2
- Compile-time generation: Zero runtime overhead
- Incremental builds: Only regenerates when
.httpfiles change - Parallel execution: Generated tests can run in parallel
- Memory efficient: No reflection or dynamic compilation at runtime
You can customize the behavior using MSBuild properties:
<PropertyGroup>
<!-- Include .http files in the project -->
<AdditionalFileItemNames>$(AdditionalFileItemNames);HttpFile</AdditionalFileItemNames>
</PropertyGroup>
<ItemGroup>
<HttpFile Include="**/*.http" />
</ItemGroup>Use preprocessor directives to include/exclude specific tests:
#if DEBUG
// Debug-specific test generation
#endif- Unit Tests: Test individual endpoints with mocked dependencies
- Integration Tests: Test complete API flows with real HTTP calls
- Contract Tests: Verify API contracts match expectations
# Success scenarios
GET https://api.example.com/users
EXPECTED_RESPONSE_STATUS 200
EXPECTED_RESPONSE_HEADER content-type: application/json
# Error scenarios
GET https://api.example.com/users/999999
EXPECTED_RESPONSE_STATUS 404
# Authentication scenarios
GET https://api.example.com/protected
Authorization: Bearer invalid-token
EXPECTED_RESPONSE_STATUS 401Works seamlessly with the REST Client extension
Compatible with built-in HTTP client in IntelliJ IDEA, WebStorm, and Rider
Export Postman collections to .http format for automated testing
- .NET SDK 8.0 or later
- Compatible IDE with
.httpfile support (optional)
git clone https://github.com/christianhelle/httptestgen.git
cd httptestgen/src
dotnet build HttpTestGen.Core/HttpTestGen.Core.csproj
dotnet build HttpTestGen.XunitGenerator/HttpTestGen.XunitGenerator.csproj
dotnet build HttpTestGen.TUnitGenerator/HttpTestGen.TUnitGenerator.csproj# Note: Requires .NET 9 SDK for tests
dotnet test HttpTestGen.Core.Tests/HttpTestGen.Core.Tests.csprojdotnet pack HttpTestGen.XunitGenerator/HttpTestGen.XunitGenerator.csproj
dotnet pack HttpTestGen.TUnitGenerator/HttpTestGen.TUnitGenerator.csprojContributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
- Fork the repository
- Clone your fork
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
- Follow existing naming conventions
- Add XML documentation for public APIs
- Include unit tests for new features
- Update README for user-facing changes
This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by the REST Client extension for Visual Studio Code
- Built on top of .NET Source Generators
- Thanks to the xUnit and TUnit communities for excellent testing frameworks
Q: Tests are not being generated
A: Ensure your .http files are included in the project and the NuGet package is properly referenced with PrivateAssets="all".
Q: Generated tests don't compile A: Check that your HTTP syntax is valid and all required NuGet packages are installed.
Q: Tests fail with connection errors A: Verify that the target APIs are accessible from your test environment.

