Add e2e tests

This commit is contained in:
2026-02-18 00:03:59 +04:00
parent d197e90103
commit 4b3230bb27
26 changed files with 4490 additions and 3 deletions

198
e2e/output_test.go Normal file
View File

@@ -0,0 +1,198 @@
package e2e
import (
"encoding/json"
"strings"
"testing"
"go.yaml.in/yaml/v4"
)
// --- JSON output structure verification ---
func TestJSONOutputHasStatFields(t *testing.T) {
t.Parallel()
cs := newCaptureServer()
defer cs.Close()
res := run("-U", cs.URL, "-r", "3", "-q", "-o", "json")
assertExitCode(t, res, 0)
out := res.jsonOutput(t)
// Verify total has all stat fields
if out.Total.Count.String() != "3" {
t.Errorf("expected count 3, got %s", out.Total.Count.String())
}
if out.Total.Min == "" {
t.Error("expected min to be non-empty")
}
if out.Total.Max == "" {
t.Error("expected max to be non-empty")
}
if out.Total.Average == "" {
t.Error("expected average to be non-empty")
}
if out.Total.P90 == "" {
t.Error("expected p90 to be non-empty")
}
if out.Total.P95 == "" {
t.Error("expected p95 to be non-empty")
}
if out.Total.P99 == "" {
t.Error("expected p99 to be non-empty")
}
}
func TestJSONOutputResponseStatFields(t *testing.T) {
t.Parallel()
cs := newCaptureServer()
defer cs.Close()
res := run("-U", cs.URL, "-r", "5", "-q", "-o", "json")
assertExitCode(t, res, 0)
out := res.jsonOutput(t)
stat, ok := out.Responses["200"]
if !ok {
t.Fatal("expected 200 in responses")
}
if stat.Count.String() != "5" {
t.Errorf("expected response count 5, got %s", stat.Count.String())
}
if stat.Min == "" || stat.Max == "" || stat.Average == "" {
t.Error("expected min/max/average to be non-empty")
}
}
func TestJSONOutputMultipleStatusCodes(t *testing.T) {
t.Parallel()
// Create servers with different status codes
srv200 := statusServer(200)
defer srv200.Close()
srv404 := statusServer(404)
defer srv404.Close()
// We can only target one URL, so use a single server
// Instead, test that dry-run produces the expected structure
res := run("-U", "http://example.com", "-r", "3", "-z", "-q", "-o", "json")
assertExitCode(t, res, 0)
out := res.jsonOutput(t)
// dry-run should have "dry-run" key
stat := out.Responses["dry-run"]
if stat.Count.String() != "3" {
t.Errorf("expected dry-run count 3, got %s", stat.Count.String())
}
}
func TestJSONOutputIsValidJSON(t *testing.T) {
t.Parallel()
cs := newCaptureServer()
defer cs.Close()
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "json")
assertExitCode(t, res, 0)
// Verify it's valid JSON
var raw map[string]any
if err := json.Unmarshal([]byte(res.Stdout), &raw); err != nil {
t.Fatalf("stdout is not valid JSON: %v", err)
}
// Verify top-level structure
if _, ok := raw["responses"]; !ok {
t.Error("expected 'responses' key in JSON output")
}
if _, ok := raw["total"]; !ok {
t.Error("expected 'total' key in JSON output")
}
}
// --- YAML output structure verification ---
func TestYAMLOutputIsValidYAML(t *testing.T) {
t.Parallel()
cs := newCaptureServer()
defer cs.Close()
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "yaml")
assertExitCode(t, res, 0)
var raw map[string]any
if err := yaml.Unmarshal([]byte(res.Stdout), &raw); err != nil {
t.Fatalf("stdout is not valid YAML: %v", err)
}
if _, ok := raw["responses"]; !ok {
t.Error("expected 'responses' key in YAML output")
}
if _, ok := raw["total"]; !ok {
t.Error("expected 'total' key in YAML output")
}
}
func TestYAMLOutputHasStatFields(t *testing.T) {
t.Parallel()
cs := newCaptureServer()
defer cs.Close()
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "yaml")
assertExitCode(t, res, 0)
assertContains(t, res.Stdout, "count:")
assertContains(t, res.Stdout, "min:")
assertContains(t, res.Stdout, "max:")
assertContains(t, res.Stdout, "average:")
assertContains(t, res.Stdout, "p90:")
assertContains(t, res.Stdout, "p95:")
assertContains(t, res.Stdout, "p99:")
}
// --- Table output content verification ---
func TestTableOutputContainsHeaders(t *testing.T) {
t.Parallel()
cs := newCaptureServer()
defer cs.Close()
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "table")
assertExitCode(t, res, 0)
// Table should contain column headers
assertContains(t, res.Stdout, "Response")
assertContains(t, res.Stdout, "Count")
assertContains(t, res.Stdout, "Min")
assertContains(t, res.Stdout, "Max")
}
func TestTableOutputContainsStatusCode(t *testing.T) {
t.Parallel()
cs := newCaptureServer()
defer cs.Close()
res := run("-U", cs.URL, "-r", "1", "-q", "-o", "table")
assertExitCode(t, res, 0)
assertContains(t, res.Stdout, "200")
}
// --- Version output format ---
func TestVersionOutputFormat(t *testing.T) {
t.Parallel()
res := run("-v")
assertExitCode(t, res, 0)
lines := strings.Split(strings.TrimSpace(res.Stdout), "\n")
if len(lines) < 4 {
t.Fatalf("expected at least 4 lines in version output, got %d: %s", len(lines), res.Stdout)
}
assertContains(t, lines[0], "Version:")
assertContains(t, lines[1], "Git Commit:")
assertContains(t, lines[2], "Build Date:")
assertContains(t, lines[3], "Go Version:")
}