Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions demo/Tests/001-Customers/001-Add-Customer-test.csx
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,17 @@ await tp.Test("Customer should be created successfully.", async () =>
// var body = tp.Request.GetBody().ToJson();
// var id = (long)body["Id"];
});

await tp.Test("Customer data should be valid.", async () =>
{
dynamic customer = await tp.Request.GetBodyAsExpandoAsync();

// TeaPie extends Xunit.Assert with additional assertion methods for more expressive tests.
// Use NotNullOrEmpty to verify that a string value is present.
NotNullOrEmpty((string)customer.firstName);
NotNullOrEmpty((string)customer.lastName);
NotNullOrEmpty((string)customer.email);

// Use GreaterThan to verify that a numeric value exceeds a threshold.
GreaterThan((long)customer.id, 0L);
});
2 changes: 2 additions & 0 deletions docs/docs/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@
href: commands.md
- name: Directives
href: directives.md
- name: Xunit.Assert Extensions
href: xunit-assert-extensions.md
142 changes: 142 additions & 0 deletions docs/docs/xunit-assert-extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Xunit.Assert Extensions

TeaPie extends the default `Xunit.Assert` with additional assertion methods to make your tests more expressive and provide better failure messages.

Since `Xunit.Assert` is **statically imported** in all script files, you can use these methods directly — **no prefix needed**.

## Comparison Assertions

These methods work for **any type implementing `IComparable<T>`** (e.g., `int`, `long`, `DateTime`, `string`, etc.).
For floating-point types (`double` and `float`), additional overloads with an **epsilon** parameter are provided to account for floating-point imprecision.

### GreaterThan

Verifies that `value` is greater than `limit`.

```csharp
GreaterThan(value, limit);
GreaterThan(value, limit, epsilon); // For double and float
```

**Example:**

```csharp
tp.Test("Response time should be acceptable.", () =>
{
var responseTimeMs = tp.Response.Headers.Age?.TotalMilliseconds ?? 0;
GreaterThan(responseTimeMs, 0); // More readable than: True(responseTimeMs > 0)
});
```

### GreaterThanOrEqual

Verifies that `value` is greater than or equal to `limit`.

```csharp
GreaterThanOrEqual(value, limit);
GreaterThanOrEqual(value, limit, epsilon); // For double and float
```

### LessThan

Verifies that `value` is less than `limit`.

```csharp
LessThan(value, limit);
LessThan(value, limit, epsilon); // For double and float
```

**Example:**

```csharp
tp.Test("Status code should be a client error.", () =>
{
var statusCode = tp.Response.StatusCode();
GreaterThanOrEqual(statusCode, 400);
LessThan(statusCode, 500);
});
```

### LessThanOrEqual

Verifies that `value` is less than or equal to `limit`.

```csharp
LessThanOrEqual(value, limit);
LessThanOrEqual(value, limit, epsilon); // For double and float
```

### Epsilon Parameter

When comparing `double` or `float` values, an **epsilon** parameter can be specified to define the maximum allowed difference for two values to be considered equal. This is useful when dealing with floating-point arithmetic imprecision.

```csharp
tp.Test("Price should be within acceptable range.", () =>
{
var price = tp.GetVariable<double>("ItemPrice");
GreaterThan(price, 0.0, 0.001); // price must be > 0.001
LessThan(price, 1000.0, 0.001); // price must be < 999.999
});
```

## Null or Empty Assertions

These methods apply to both **strings** and **collections**.

### NullOrEmpty

Verifies that a string or collection is `null` or empty.

```csharp
NullOrEmpty(value); // string
NullOrEmpty(collection); // IEnumerable<T>
```

**Example:**

```csharp
tp.Test("Error list should be empty.", () =>
{
var errors = tp.GetVariable<string[]>("ValidationErrors");
NullOrEmpty(errors);
});
```

### NotNullOrEmpty

Verifies that a string or collection is **not** `null` and **not** empty.

```csharp
NotNullOrEmpty(value); // string
NotNullOrEmpty(collection); // IEnumerable<T>
```

**Example:**

```csharp
await tp.Test("Response body should not be empty.", async () =>
{
var body = await tp.Response.GetBodyAsStringAsync();
NotNullOrEmpty(body);
});
```

## JsonContains

Verifies that a JSON string contains another JSON object. Optionally, specific properties can be excluded from the comparison.

```csharp
JsonContains(container, contained);
JsonContains(container, contained, "propertyToIgnore", "anotherProperty");
```

**Example:**

```csharp
await tp.Test("Response should contain the expected customer data.", async () =>
{
var responseBody = await tp.Response.GetBodyAsStringAsync();
var expected = """{ "name": "Alice", "age": 30 }""";
JsonContains(responseBody, expected);
});
```
Loading
Loading