diff --git a/Directory.Build.props b/Directory.Build.props
index 59ed3a3..83b1ab4 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,5 +1,5 @@
- 0.3.3
+ 0.3.4
\ No newline at end of file
diff --git a/src/QAToolKit.Engine.HttpTester.Test/Exceptions/QAToolKitEngineHttpTesterExceptionTests.cs b/src/QAToolKit.Engine.HttpTester.Test/Exceptions/QAToolKitEngineHttpTesterExceptionTests.cs
index 0fdd524..74247c9 100644
--- a/src/QAToolKit.Engine.HttpTester.Test/Exceptions/QAToolKitEngineHttpTesterExceptionTests.cs
+++ b/src/QAToolKit.Engine.HttpTester.Test/Exceptions/QAToolKitEngineHttpTesterExceptionTests.cs
@@ -1,6 +1,5 @@
using QAToolKit.Engine.HttpTester.Exceptions;
using System;
-using System.Runtime.Serialization;
using Xunit;
namespace QAToolKit.Engine.HttpTester.Test.Exceptions
diff --git a/src/QAToolKit.Engine.HttpTester.Test/HttpTestAsserterTests.cs b/src/QAToolKit.Engine.HttpTester.Test/HttpTestAsserterTests.cs
index 581f806..6919688 100644
--- a/src/QAToolKit.Engine.HttpTester.Test/HttpTestAsserterTests.cs
+++ b/src/QAToolKit.Engine.HttpTester.Test/HttpTestAsserterTests.cs
@@ -5,13 +5,11 @@
using System.Linq;
using System.Net;
using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Xunit;
namespace QAToolKit.Engine.HttpTester.Test
-{
+{
public class HttpTestAsserterTests
{
[Fact]
@@ -120,7 +118,7 @@ public async Task HttpTestAsserterHeaderMissing_Fails()
var httpDuration = client.HttpDuration;
Assert.Throws(() => asserter
.ResponseContentContains("scott")
- .RequestDurationEquals(duration, (x) => x < 2000)
+ .RequestDurationEquals(duration, (x) => x < Convert.ToInt64("2000"), "x < 2000")
.RequestDurationEquals(httpDuration, (x) => x < 1800)
.ResponseStatusCodeEquals(HttpStatusCode.OK)
.ResponseContentTypeEquals("application/json")
diff --git a/src/QAToolKit.Engine.HttpTester/Exceptions/QAToolKitEngineHttpTesterException.cs b/src/QAToolKit.Engine.HttpTester/Exceptions/QAToolKitEngineHttpTesterException.cs
index f050139..e3814ba 100644
--- a/src/QAToolKit.Engine.HttpTester/Exceptions/QAToolKitEngineHttpTesterException.cs
+++ b/src/QAToolKit.Engine.HttpTester/Exceptions/QAToolKitEngineHttpTesterException.cs
@@ -1,5 +1,4 @@
using System;
-using System.Runtime.Serialization;
namespace QAToolKit.Engine.HttpTester.Exceptions
{
diff --git a/src/QAToolKit.Engine.HttpTester/HttpTestAsserter.cs b/src/QAToolKit.Engine.HttpTester/HttpTestAsserter.cs
index 776ffb1..ec3aa55 100644
--- a/src/QAToolKit.Engine.HttpTester/HttpTestAsserter.cs
+++ b/src/QAToolKit.Engine.HttpTester/HttpTestAsserter.cs
@@ -3,6 +3,7 @@
using QAToolKit.Engine.HttpTester.Models;
using System;
using System.Collections.Generic;
+using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
@@ -24,7 +25,8 @@ public class HttpTestAsserter : IHttpTestAsserter
///
public HttpTestAsserter(HttpResponseMessage httpResponseMessage)
{
- _httpResponseMessage = httpResponseMessage ?? throw new ArgumentNullException($"{nameof(httpResponseMessage)} is null.");
+ _httpResponseMessage = httpResponseMessage ??
+ throw new ArgumentNullException($"{nameof(httpResponseMessage)} is null.");
_assertResults = new List();
}
@@ -40,8 +42,8 @@ public IEnumerable AssertAll()
///
/// HTTP body contains a string (ignores case)
///
- ///
- ///
+ /// Check if the HTTP response body contains a keyword.
+ /// Use case sensitive string comparison.
///
public IHttpTestAsserter ResponseContentContains(string keyword, bool caseInsensitive = true)
{
@@ -52,20 +54,27 @@ public IHttpTestAsserter ResponseContentContains(string keyword, bool caseInsens
var bodyString = _httpResponseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult();
- _assertResults.Add(new AssertResult()
+ var assertResult = new AssertResult()
{
- Name = nameof(ResponseContentContains),
- Message = $"Body contains '{keyword}'.",
- IsTrue = caseInsensitive ? StringHelper.ContainsCaseInsensitive(bodyString, keyword) : bodyString.Contains(keyword)
- });
+ Name = nameof(ResponseContentContains)
+ };
+
+ assertResult.IsTrue = caseInsensitive
+ ? StringHelper.ContainsCaseInsensitive(bodyString, keyword)
+ : bodyString.Contains(keyword);
+ assertResult.Message = assertResult.IsTrue
+ ? $"Response body contains keyword '{keyword}'."
+ : $"Response body does not contain keyword '{keyword}'.";
+
+ _assertResults.Add(assertResult);
return this;
}
-
+
///
/// Check if the response contains specified Content Type
///
- ///
+ /// Check if the response content type equals the parameter.
///
///
public IHttpTestAsserter ResponseContentTypeEquals(string contentType)
@@ -75,12 +84,12 @@ public IHttpTestAsserter ResponseContentTypeEquals(string contentType)
throw new ArgumentNullException($"{nameof(contentType)} is null.");
}
- var bodyString = _httpResponseMessage.Content.Headers.ContentType;
-
+ var responseContentType = _httpResponseMessage.Content.Headers.ContentType.MediaType;
+
_assertResults.Add(new AssertResult()
{
Name = nameof(ResponseContentTypeEquals),
- Message = $"Response content-type equals '{contentType}'.",
+ Message = $"Expected content-type = '{contentType}', actual = '{responseContentType}'.",
IsTrue = _httpResponseMessage.Content.Headers.ContentType.MediaType == contentType
});
@@ -90,18 +99,44 @@ public IHttpTestAsserter ResponseContentTypeEquals(string contentType)
///
/// Verify request duration
///
- ///
- ///
+ /// Actual duration of the HTTP request execution
+ /// It's a function that validates the duration
+ /// String predicateFunctionExpression for the report. If set it will be used in the assert result message.
///
- public IHttpTestAsserter RequestDurationEquals(long duration, Func predicateFunction)
+ public IHttpTestAsserter RequestDurationEquals(long duration, Expression> predicateFunction, string predicateFunctionExpression = null)
{
- var isTrue = predicateFunction.Invoke(duration);
- _assertResults.Add(new AssertResult()
+ var isTrue = predicateFunction.Compile()(duration);
+
+ var assertResult = new AssertResult()
{
Name = nameof(RequestDurationEquals),
- Message = $"Duration is '{duration}'.",
IsTrue = isTrue
- });
+ };
+
+ if (isTrue)
+ {
+ if (string.IsNullOrEmpty(predicateFunctionExpression))
+ {
+ assertResult.Message = $"Duration is '{duration}ms' and is valid.";
+ }
+ else
+ {
+ assertResult.Message = $"Duration is '{duration}ms' and is valid with predicateFunctionExpression '{predicateFunctionExpression}'.";
+ }
+ }
+ else
+ {
+ if (string.IsNullOrEmpty(predicateFunctionExpression))
+ {
+ assertResult.Message = $"Duration is '{duration}ms' and is invalid.";
+ }
+ else
+ {
+ assertResult.Message = $"Duration is '{duration}ms' and is invalid with predicateFunctionExpression '{predicateFunctionExpression}'.";
+ }
+ }
+
+ _assertResults.Add(assertResult);
return this;
}
@@ -109,7 +144,7 @@ public IHttpTestAsserter RequestDurationEquals(long duration, Func p
///
/// HTTP response contains a header
///
- ///
+ /// Check if the HTTP response contains the header with the name.
///
public IHttpTestAsserter ResponseHasHttpHeader(string headerName)
{
@@ -118,12 +153,17 @@ public IHttpTestAsserter ResponseHasHttpHeader(string headerName)
throw new ArgumentNullException($"{nameof(headerName)} is null.");
}
- _assertResults.Add(new AssertResult()
+ var assertResult = new AssertResult
{
Name = nameof(ResponseHasHttpHeader),
- Message = $"Contains header '{headerName}'.",
IsTrue = _httpResponseMessage.Headers.TryGetValues(headerName, out var values)
- });
+ };
+
+ assertResult.Message = assertResult.IsTrue
+ ? $"Response message contains header '{headerName}'."
+ : $"Response message does not contain header '{headerName}'.";
+
+ _assertResults.Add(assertResult);
return this;
}
@@ -131,14 +171,15 @@ public IHttpTestAsserter ResponseHasHttpHeader(string headerName)
///
/// Verify if response code equals
///
- ///
+ /// Check if the HTTP response status code equals to this parameter.
///
public IHttpTestAsserter ResponseStatusCodeEquals(HttpStatusCode httpStatusCode)
{
_assertResults.Add(new AssertResult()
{
Name = nameof(ResponseStatusCodeEquals),
- Message = $"Expected status code is '{httpStatusCode}' return code is '{_httpResponseMessage.StatusCode}'.",
+ Message =
+ $"Expected status code = '{httpStatusCode}', actual = '{_httpResponseMessage.StatusCode}'.",
IsTrue = _httpResponseMessage.StatusCode == httpStatusCode
});
@@ -154,7 +195,7 @@ public IHttpTestAsserter ResponseStatusCodeIsSuccess()
_assertResults.Add(new AssertResult()
{
Name = nameof(ResponseStatusCodeIsSuccess),
- Message = $"Expected status code is '2xx' return code is '{_httpResponseMessage.StatusCode}'.",
+ Message = $"Expected status code = '2xx', actual = '{_httpResponseMessage.StatusCode}'.",
IsTrue = _httpResponseMessage.IsSuccessStatusCode
});
@@ -172,11 +213,11 @@ public IHttpTestAsserter ResponseBodyIsEmpty()
_assertResults.Add(new AssertResult()
{
Name = nameof(ResponseBodyIsEmpty),
- Message = $"Expected empty body, returned body is '{bodyString}'.",
+ Message = $"Expected empty response body, actual = '{bodyString}'.",
IsTrue = string.IsNullOrEmpty(bodyString)
});
return this;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/QAToolKit.Engine.HttpTester/Interfaces/IHttpTestAsserter.cs b/src/QAToolKit.Engine.HttpTester/Interfaces/IHttpTestAsserter.cs
index d621001..e9e1446 100644
--- a/src/QAToolKit.Engine.HttpTester/Interfaces/IHttpTestAsserter.cs
+++ b/src/QAToolKit.Engine.HttpTester/Interfaces/IHttpTestAsserter.cs
@@ -1,6 +1,7 @@
using QAToolKit.Engine.HttpTester.Models;
using System;
using System.Collections.Generic;
+using System.Linq.Expressions;
using System.Net;
using System.Net.Http.Headers;
@@ -18,13 +19,15 @@ public interface IHttpTestAsserter
///
///
IHttpTestAsserter ResponseContentContains(string keyword, bool caseInsensitive = true);
+
///
/// Verify request duration
///
///
///
+ ///
///
- IHttpTestAsserter RequestDurationEquals(long duration, Func predicateFunction);
+ IHttpTestAsserter RequestDurationEquals(long duration, Expression> predicateFunction, string predicateFunctionExpression = null);
///
/// Verify if response code equals
///