I'm using Microsoft WebTest and want to be able to do something similar to NUnit's Assert.Fail(). The best i have come up with is to throw new webTestException() but this shows in the test results as an Error rather than a Failure.
Other than reflecting on the WebTest to set a private member variable to indicate the failure, is there something I've missed?
EDIT: I have also used the Assert.Fail() method, but this still shows up as an error rather than a failure when used from within WebTest, and the Outcome property is read-only (has no public setter).
EDIT: well now I'm really stumped. I used reflection to set the Outcome property to Failed but the test still passes!
Here's the code that sets the Oucome to failed:
public static class WebTestExtensions
{
public static void Fail(this WebTest test)
{
var method = test.GetType().GetMethod("set_Outcome", BindingFlags.NonPublic | BindingFlags.Instance);
method.Invoke(test, new object[] {Outcome.Fail});
}
}
and here's the code that I'm trying to fail:
public override IEnumerator<WebTestRequest> GetRequestEnumerator()
{
this.Fail();
yield return new WebTestRequest("http://google.com");
}
Outcome is getting set to Oucome.Fail but apparently the WebTest framework doesn't really use this to determine test pass/fail results.
Set the Outcome property to Fail:
Outcome = Outcome.Fail;
There's also an Assert.Fail() in the Microsoft.VisualStudio.QualityTools.UnitTestFramework assembly.
The Outcome property will set the public at vsts 2010 :-)
You make a test always fail by adding a validation rule that always fails. For example, you could write a fail validation rule like this:
public class FailValidationRule : ValidationRule
{
public override void Validate(object sender, ValidationEventArgs e)
{
e.IsValid = false;
}
}
Then attach the new validation rule you your webtest's ValidateResponse event, like so:
public class CodedWebTest : WebTest
{
public override IEnumerator<WebTestRequest> GetRequestEnumerator()
{
WebTestRequest request1 = new WebTestRequest("http://www.google.com");
FailValidationRule failValidation = new FailValidationRule();
request1.ValidateResponse += new EventHandler<ValidationEventArgs>(failValidation.Validate);
yield return request1;
}
}
A solution that would work in declarative tests (as well as coded) is:
write a Validation Rule that fails when a certain Context Parameter (e.g. 'FAIL') is present in the Context
when you want to trigger the failure, set the Context Parameter and call WebTest.Stop()
add the Validation Rule as a WebTest-level rule (not request-level) so that it runs on all requests
I think that's as concise as it can be done.
First off, I'm working with VB.net, but I also tried to set the outcome to fail before finding out it does not work (which brought me here).
I finally managed to do it by just throwing an exception :
Public Overrides Sub PostRequest(ByVal sender As Object, ByVal e As PostRequestEventArgs)
If YourTest = True Then
Throw New WebTestException("My test Failed")
End If
MyBase.PostRequest(sender, e)
End Sub
I know this topic is old but I hope it helps someone anyway :)
Set the value of Outcome in the PostWebTest event handler.
Related
My class requires additional information to properly output its status, so I've added a custom PrintSelf method taking the appropriate parameters.
However, I'm afraid there are still calls to ToString in my large project, which were not replaced by the new method. How can I find those improper calls to ToString?
I'm using VS 2015, but it does not seem to have this ability.
Throwing an exception in ToString would be an obvious way, but I don't want to do that for two reasons:
ToString can still perform a different job and output something not depending on the added parameter.
There is no way to get full code coverage, meaning it would only find a few instances of implicit calls, but not (reliably) all of them.
To override ToString and log the caller you can do like this
public override string ToString()
{
StackTrace stackTrace = new StackTrace();
StackFrame[] stackFrames = stackTrace.GetFrames();
StackFrame callingFrame = stackFrames[1];
MethodInfo method = callingFrame.GetMethod();
YourLogingMethod(method.DeclaringType.Name + "." + method.Name);
return base.ToString();
}
You can make usage of the Obsolete Attribute :
public class MyFirstClass
{
//true or false parameters indicates whether to throw
// a compile error (true) or warning (false)
[Obsolete("Please use the method PrintSelf() instead of ToString()", false)]
public overrides string ToString()
{
//Whatever code you want here
return "";
}
}
public class MySecondClass
{
public void Test()
{
mfc = new MyFirstClass();
mfc.ToString(); //Here you will get a compiler warning
}
}
So this will let you know inside Visual Studio of all the calls made to this function. Since it is only a warning, it is still possible to use it.
(note : Sorry if the syntax is not correct, I'm normally a VB .Net developper, feel free to correct it if needed.)
I'm trying to learn automation with Selenium Webdriver using c#. I have my custom method Assert. What I did to continue the test after catching an AssertFailedException is using try-catch below is my code
public static void assert(string value, IWebElement element)
{
try
{
Assert.AreEqual(value, element.Text);
}
catch (AssertFailedException e)
{
Console.WriteLine(e.Message.ToString());
}
}
My problem is it catches all AssertFailedException(which is my goal) but the result of the test is PASSED in visual studio. My question is, how do I implement Continue on Failure and Fail the test if the Console contains Exceptions. Thankyou in advance guys!
As far as I understand, you want to do several checks inside your test, and at the very end of it to determine whether any of of them failed. You may need to write some custom code to achieve this. For example, you may introduce a class Assertion:
internal class Assertion
{
private readonly string title;
private readonly object expected;
private readonly object actual;
public Assertion(string title, object expected, object actual)
{
this.title = title;
this.expected = expected;
this.actual = actual;
}
public bool IsMatch()
{
return this.actual == this.expected;
}
public override string ToString()
{
return $"Title: {title}. Expected: {expected}. Actual: {actual}";
}
}
When your test is running, you will create new instances of Assertion class and store them in a list. At the end of the test, you can use the following method:
private static void VerifyAssertions(Assertion[] assertions)
{
var failedAssertions = assertions.Where(a => !a.IsMatch()).ToArray();
if (failedAssertions.Any())
{
throw new AssertFailedException(string.Join<Assertion>("; ", failedAssertions));
}
}
You could try using verify instead of assert for minor checks. Assert by default indicates a major checkpoint and script execution will be terminated on fail and if you catch that exception the reporting will be ignored - this is expected behaviour. However, a verify indicates that the script can continue even on fail - in this case the failed step will be reported and the script will continue.
To put it simply, use assert when you don't want the script to proceed on failure and use verify when you want the script to report the failure and proceed.
Can anyone help with the following code?
I'm trying to pass value from server to client via RIA Silverlight, but keep getting NullReferenceException.
I have removed all other attempts that I have tried and have just posted last attempt.
Server-side Code
namespace Web.UI.SilverlightDomainServices
{
// Implements application logic using the SilverlightDBEntities context.
// TODO: Add your application logic to these methods or in additional methods.
// TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
// Also consider adding roles to restrict access as appropriate.
// [RequiresAuthentication]
[EnableClientAccess()]
public class VideoAdvertDomainService : LinqToEntitiesDomainService<SilverlightDBEntities>
{
// TODO:
// Consider constraining the results of your query method. If you need additional input you can
// add parameters to this method or create additional query methods with different names.
// To support paging you will need to add ordering to the 'at_AdvertVideoAdvertisement' query.
string strMonthYear = DateTime.Now.ToString("MMMM-yyyy");
[Invoke]
public List<string> GetMediaURLBasedOnMonthYear(string strMonthYear)
{
return (from p in this.ObjectContext.at_AdvertVideoAdvertisement
where p.AdvertMediaMonthYear == strMonthYear
select p.AdvertMediaURL).ToList();
}
public IQueryable<at_AdvertVideoAdvertisement> GetAt_AdvertVideoAdvertisement()
{
return this.ObjectContext.at_AdvertVideoAdvertisement;
}
}
}
Client-side Code
namespace Web.Silverlight
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private VideoAdvertDomainContext ctx = new VideoAdvertDomainContext();
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
string strMonthYear = DateTime.Now.ToString("MMMM-yyyy");
VideoAdvertDomainContext DomainContext = new VideoAdvertDomainContext();
InvokeOperation iv = DomainContext.GetMediaURLBasedOnMonthYear("September-2012");
iv.Value.ToString();
PlaylistItem item = new PlaylistItem();
item.MediaSource = new Uri(iv.Value.ToString());
item.DeliveryMethod = Microsoft.SilverlightMediaFramework.Plugins.Primitives.DeliveryMethods.AdaptiveStreaming;
MP.Playlist.Add(item);
}
}
}
Without seeing the stack trace from the exception, I have to guess.
Possibility 1
It could be that ObjectContext is null and therefore, this line will throw the exception you are getting.
return (from p in this.ObjectContext.at_AdvertVideoAdvertisement
where p.AdvertMediaMonthYear == strMonthYear
select p.AdvertMediaURL).ToList();
Possibility 2
Is there a chance that the contents of this.ObjectContext.at_AdvertVideoAdvertisement are null?
If so, p could be null, which would cause the query to throw the exception.
Possibility 3
I suspect the offending line is:
iv.Value.ToString();
This line does nothing, but you also repeat this a couple of lines later in a useful context, so perhaps the first declaration is a mistake. However, this assumes that the InvokeOperation value returned by VideoAdvertDomainContext.GetMediaURLBasedOnMonthYear is not null and that its Value property is not null. This may not be the case.
Recommendation
I recommend placing a breakpoint on those lines and seeing what the variables look like in the debugger to track down the null reference. From there, you can start to work out why it is null and either make it so that it isn't, or fix your code so that it copes appropriately with null references.
I want to stub a function that receive 2 boolean parameters. The first is required and the second is optional. If I try to send Arg.Is.Anything to the first but without information for the second, I receive an error:
System.InvalidOperationException : When using Arg, all arguments must be defined using Arg.Is, Arg.Text, Arg.List, Arg.Ref or Arg.Out. 2 arguments expected, 1 have been defined.
Here is a sample of my class to stub:
public interface IOptionalParameterTester
{
bool IsValid(bool mustCheck, bool checkInDatabase = true);
}
public class OptionalParameterTester : IOptionalParameterTester
{
public bool IsValid(bool mustCheck, bool checkInDatabase = true)
{
if (checkInDatabase)
return true;
else
return false;
}
}
And here is a sample of the test:
[Test]
public void ValidateProducerTest()
{
IOptionalParameterTester optionalParameter = MockRepository.GenerateStub<IOptionalParameterTester>();
optionalParameter.Stub(x => x.IsValid(Arg<bool>.Is.Anything)).Return(true);
}
In this case, if I want the test to pass without error, I must define the same information that for the first (Arg.Is.Anything) or a specific boolean value like true or false.
If I set anything other than Arg.Is.Anything for the first parameter, I don't have any error.
Is it a bug?
Can I setup an option in RhinoMock to don't have to define a value for each optional parameter?
If there is no setup, is there a better thing to do to handle this case (Best practice, pattern, etc.)?
Thank you.
I think I understand what you are trying to do but, since it seems that this is a limitation of Rhino Mocks (we can get to that conclusion from the error message you are receiving) I would suggest to change your testing strategy.
Try doing the following:
[Test]
public void ValidateProducerTest()
{
bool anyBooleanValue = true;
IOptionalParameterTester optionalParameter = MockRepository.GenerateStub<IOptionalParameterTester>();
optionalParameter.Stub(x => x.IsValid(anyBooleanValue)).Return(true);
}
I know that on your test you want Rhino Mocks to ignore the first parameter and that it takes the optional second one but, depending on the logic you want to test, just hard code the first parameter and Rhino Mocks should not complain.
As long as on your test it is clearly stated that the first parameter's value is not relevant your test is valid and readable.
Just had a similar issue myself, try
optionalParameter.Stub(x => x.IsValid()).IgnoreArguments().Return(true);
This is quite an old question now, but I landed on this page because I was having issues with AssertWasCalled and optional parameters.
Eventually, I solved my problem using the following syntax found on this page: http://petermorlion.blogspot.com/2012/11/rhinomock-assertwascalled-vs.html.
string expectedMessage = "RhinoMocks baby!";
string actualMessage = "RhinoMocks dude!";
var fooMock = MockRepository.GenerateMock<ifoo>();
fooMock.Bar(actualMessage);
var calls = fooMock.GetArgumentsForCallsMadeOn(x => x.Bar(string.Empty), o => o.IgnoreArguments());
Assert.AreEqual(1, calls.Count);
var arguments = calls[0];
Assert.AreEqual(expectedMessage, arguments[0]);
I am new to developing in .NET and C#, but have been a long-time developer, working with C, C++, Java, PHP, etc.
I have an MVC3 extension class for my data models that refers to the database. It is set as "private static" in the class, but I think that it is not keeping up with database changes. In other words, when I change data in the controllers, those changes aren't "noticed" in the db because it is static. Currently, I am creating and disposing of the variable for each use, to compensate.
My questions are:
Am I correct that a static db variable could behave that way?
Is it necessary to dispose of the dynamic variable in the static class, or will garbage collection still take care of it automatically?
Here is a relevant snippet of the class:
namespace PBA.Models {
using System;
using System.Text.RegularExpressions;
using PBA.Models;
using PBA.Controllers;
public static class Extensions {
private static PbaDbEntities db = null;
public static PbaDbEntities GetDb() {
// TODO: find out about static memory/disposal, etc.
//
if (db != null) {
db.Dispose();
}
db = new PbaDbEntities();
return db;
}
public static string GetCheckpointState(this Activity activity, long memberProjectId) {
GetDb(); // TODO: Do I need to do this each time, or will a one-time setting work?
string state = CheckpointController.CHECKPOINT_STATUS_NOT_STARTED;
try {
var sub = db.ActivitySubmissions.
Where(s => s.activityId == activity.activityId).
Where(s => s.memberProjectId == memberProjectId).
OrderByDescending(s => s.submitted).
First();
if (sub != null) {
state = sub.checkpointStatusId;
}
}
catch (Exception e) {
// omitted for brevity
}
return state;
}
}
}
Your code will fail horribly in production.
DataContexts are not thread-safe; you must not share a context between requests.
Never put mutable objects in static fields in multi-threaded applications.
Ignoring exceptions that way is a terrible idea, if you don't want to handle exceptions just don't try/catch, or catch & rethrow. Think about it like this, after you've buried the exception, your program is in an invalid state, b/c something you have no control over error'd out. Now, b/c you've buried the exception, your program can continue to operate but it's in a bad state.
If your code makes it to production, 3.5 yrs from now some jr. programmer is going to get involved in some middle of the night firestorm because all of a sudden the website is broken, even though it used to work. It will be completely impossible to track down where the exception is happening so, this poor guy is going to spend 48 straight hours adding logging code all over the place to track down the problem. He will find that some DBA somewhere decided to rename the column MemberProjectId to MemberProjectIdentifier, which caused your linq to blow up.
Think of the children, handle exceptions, don't bury them.
btw - yes, i have been that guy that has to figure out these types of mistakes.
It seems like you need to read about mvc3 and entity framework before writing coding and asking in here for help on something that's coded full of bad practices.
Answering your questions:
1- no
2- makes no sense as the answer to 1
Do it right, here are some useful documentation: http://msdn.microsoft.com/en-us/library/ie/gg416514(v=vs.98).aspx
EDIT: Adding some explicit fix
You could access your dbcontext from an static class, something like this:
var context = DbProvider.CurrentDb;
The idea is to access your db from here always: from your extension methods and from your controller actions.
Then, the implementation of the DbProvider.CurrentDb will be something like this:
public static classDbProvider {
public static void Initialize(){
HttpContext.Current.ApplicationInstance.BeginRequest += CreateDb;
HttpConetxt.Current.ApplicationInstance.EndRequest += DisposeDb;
}
private static void CreateDb(object sender, EventArgs e) {
HttpContext.Items.Add("CurrentDb", new PbaDbEntities(););
}
private static void DisposeDb(object sender, EventArgs e)
{
Current.Dispose();
HttpContext.Items.Remove("CurrentDb");
}
public static PbaDbEntities CurrentDb{
get {
return (PbaDbEntities)HttpContext.Current.Items["CurrentDb"];
}
}
}
As you can see, it will create a new Db per each request and it will be available ONLY in that request. In that way, your db will be disposed at the end of each request. This pattern is called Open-Session-in-View.
Finally, you need to initialize the DbProvider calling the method
Initialize() in your Global.asax file, in the event Application_start.
Hope it helps.
I don't have any idea of the context here-- if db is simply a connection-like object or not, but it appears you are throwing away and recreating whatever it is unnecessarily.
Best to create a property (for whatever your doing) so to be consistent.
private static Thing _thing;
private static Thing thing{
get{
if(_thing==null){
_thing=new Thing();
}
return _thing;
}
}