I am learning how to do unit testing. I tried to search for how to do testing for a button click event but couldn't find an answer that I could understand.
How can I check if TextBlock_MouseDown event was raised and followed by reponse from PostMethod, which must not be null. My issue is, I can't find a way or don't know how to check TextBlock_MouseDown event using NUnit.
public partial class MainWindow : Window
{
public MainWindow(){
InitializeComponent();
}
public void TextBlock_MouseDown(object sender, MouseButtonEventArgs e){
//Check return value from PostMethod
string reponse = PostMethod("myurlhere");
}
public static String PostMethod(String val){
//Code
}
}
[TestFixture]
public class TestClass
{
[Test]
public void PostMethod_IsAlive_returnHello()
{
//ARRANGE
String url = "myurlhere";
//ACT
string response = MainWindow.PostMethod(url);
//ASSERT
Assert.AreEqual("\"Hello\"", response);
}
}
If you want to to test your UI, you should use a test library for UI-Testing.
For example FlaUI (https://github.com/Roemer/FlaUI).
NUnit is used to test your code behind. For example if you want to check if PostMethod() is returning a specific value.
If you only want to check the result of PostMethod(), outsource the method to another class and test it (MainWindow will now use OutsourcedClass.PostMethod() in its code behind).
outsourced class
public class OutsourcedClass
{
public string PostMethod(string url)
{
return url;
}
}
unit test
public class OutsourcedClassTest
{
private OutsourcedClass _Instance;
[SetUp]
public void Setup()
{
_Instance = new OutsourcedClass();
}
[Test]
public void PostMethodTest()
{
string url = "foo";
Assert.AreEqual(url, _Instance.PostMethod(url));
}
}
Related
I am doing some unit tests with NUnit and NSubstiture.
I have this class:
public class Presenter
{
public Presenter()
{
}
private readonly IView _view;
public Presenter(IView view)
{
_view = view;
this._view.Loaded += OnLoaded;
}
private void OnLoaded()
{
_view.Render("Hello Word");
}
}
And I have this Interface:
public interface IView
{
event Action Loaded;
void Render(string text);
}
And I have already a unit test with the NSubstiture framework, like this:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithMockingFramework()
{
var mockView = Substitute.For<IView>();
Presenter p = new Presenter(mockView);
mockView.Loaded += Raise.Event<Action>();
mockView.Received().Render(Arg.Is<string>(s => s.Contains("Hello World")));
}
But now I want for just testing purpose, write the same unit test , but then without the NSubstiture framework:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
IView view;
Presenter MockingVIew = new Presenter(view);
}
But how to do this?
Thank you
I try it like this:
public class FakePresenter : IView
{
public event Action Loaded;
public void Render(string text)
{
}
}
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
//FakeMockingVIew = new Presenter(view);
FakePresenter fPresenter = new FakePresenter();
Presenter p = new Presenter(fPresenter);
fPresenter.Loaded += Raise.Event<Action>();
fPresenter.Received();
Assert.That(fPresenter, Is.EqualTo());
}
If you no longer want to use the mocking framework, nothing is stopping you from creating a class derived from IView yourself and using that as the dependency in the test
public class MyTestClass {
public class FakePresenter : IView {
public event Action Loaded = delegate { };
public void Render(string text) {
RenderedText = text;
}
public string RenderedText { get; private set; }
public void Load() {
Loaded();
}
}
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework() {
//Arrange
var fake = new FakePresenter();
var subject = new Presenter(fake);
var expected = "Hello Word";
//Act
fake.Load();
var actual = fake.RenderedText;
//Assert
Assert.AreEqual(expected, actual);
}
}
The above implementation of the dependency exposes a Load() method to raise the event for all subscribers and also a RenderedText property to capture the text passed into the Render method so that an assertion can be made based on the value.
When you used NSubstitute, you had to tell the mock view to raise an event. But since the IView interface doesn't allow you to trigger the event, only add an event listener, NSubstitute does a workaroud, by attaching a special event handler, it actually triggers an event (I'm not familiar with NSubstitute, but I assume this is what happens):
// Code here says "attact an event handler", but NSubstitute recognizes this
// special event handler and raises the event to the "real" hanlders instead
mockView.Loaded += Raise.Event<Action>();
So when you move away from NSubstitute, you need to actually trigger the event the "correct" way from the fake view class:
public class FakeView : IView
{
private string RenderedText { get; private set; }
public event Action Loaded;
public void Render(string text)
{
renderedText = text;
}
public void RaiseLoaded() {
if (Loaded != null) Loaded();
}
}
Now you can easily trigger the events from your test:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
FakeView view = new FakeView();
Presenter p = new Presenter(fPresenter);
view.RaiseLoaded();
Assert.That(view.RenderedText, Is.EqualTo("Hello World"));
}
When trying to invoke a Test from a different class from where it is implemented, it does not execute the Parallelizable attribute, instead, it only executes the methods sequentially ( Alltest_2() and Alltest_1() ). Is there any way to invoke them so that they are executed in parallel?
Here's a code sample:
public class AO_Alarms_4 : AO_Alarms_3
{
[SetUp]
public void DefaultSetUp(){ }
[Test]
public void Alltest_Clases()
{
Alltest_2();
Alltest_1();
}
[TearDown]
public void DefaultTearDown() { }
}
[TestFixture]
[Parallelizable]
public class AO_Alarms_3 : AO_Alarms_2
{
public WebDriverFactory driver = new WebDriverFactory(Utils.Browser);
[SetUp]
public void login_2()
{
//code
}
[Test]
[Parallelizable]
public void Alltest_2()
{
test_2();
}
public void test_2()
{
//code
}
[TearDown]
public void teardown_2()
{
//code
}
}
[TestFixture]
[Parallelizable]
public class AO_Alarms_2
{
public WebDriverFactory driver = new WebDriverFactory(Utils.Browser);
[SetUp]
public void login_1()
{
//code
}
[Test]
[Parallelizable]
public void Alltest_1()
{
test1_1();
test1_2();
}
[Test]
public void test1_1()
{
//code
}
[Test]
public void test1_2()
{
//code
}
[TearDown]
public void teardown_1()
{
//code
}
}
You can't simply call tests yourself and expect to get any of the normal NUnit behavior around tests. For example, NUnit knows what to do when it calls a test with [Parallelizable] on it - and what it does is fairly complicated. Your own call is simply calling the method you wrote.
There is nothing to stop you from calling common methods within a given test, but the tests themselves have to be invoked by NUnit.
If you can rephrase or ask another question about what you are actually trying to accomplish here, we can probably give you some advice about alternatives.
i have a problem running Multiple C# Selenium Unit Test tests with one driver instance.
Please find my class as below.
Folder : Com.Main.Web.Selenium
SeleniumTestInitialize.cs is the main class which contains the driver.
[DeploymentItem(#"Resources\IEDriverServer.exe")]
public class SeleniumTestInitialize
{
public TestContext TestContext
{
get { return testContextInstance; }
set { testContextInstance = value; }
}
private TestContext testContextInstance;
public bool SeleniumExecutionTerminateFlag=false;
public SeleniumTestInitialize seleniumTestInitalize;
public FindWebDriverElement findWebDriverElement;
public JavaScriptCalls javaScriptCalls;
public OperateOnWebDriverElement operateOnWebDriverElement;
**public RemoteWebDriver driver;**
// how to use this driver object across multiple unit test classes
public string baseURL;
public void SeleniumSetup()
{
try
{
Console.WriteLine("Starting Driver...........");
seleniumTestInitalize = new SeleniumTestInitialize();
var options = new InternetExplorerOptions
{
IntroduceInstabilityByIgnoringProtectedModeSettings = true,
//ForceCreateProcessApi=true
EnableNativeEvents = false,
RequireWindowFocus = false,
IgnoreZoomLevel = true
};
driver = new InternetExplorerDriver(TestContext.DeploymentDirectory, options);
javaScriptCalls = new JavaScriptCalls(driver);
findWebDriverElement = new FindWebDriverElement(javaScriptCalls);
operateOnWebDriverElement = new OperateOnWebDriverElement(findWebDriverElement);
GoToSite(ConfigParameters.WEB_APPLICATION_URL);
driver.Manage().Window.Maximize();
}
catch (Exception e)
{
log.Debug("Error Starting Web Driver...........");
Console.WriteLine(e.StackTrace);
}
}
public bool SeleniumInitalizeCheck()
{
if (seleniumTestInitalize != null)
return true;
else
return false;
}
public void SeleniumQuit()
{
Console.WriteLine("Quitting Driver...........");
try
{
if (driver != null)
{
driver.Quit();
}
log.Info("Closing Web Driver...........");
ProcessMgn.killProcessByNames("IEDriverServer");//Make sure the process is killed
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
}
}
public void GoToSite(string urlToOpen)
{
driver.Navigate().GoToUrl(urlToOpen);
}
}
Folder com.main.tests
Test01.cs
[TestClass]
public class Test01 : SeleniumTestInitialize
{
[TestInitialize]
public void Setup()
{
SeleniumExecutionTerminateFlag = false;
if (!SeleniumInitalizeCheck())
{
SeleniumSetup();
}
}
[TestCleanup]
public void TearDown()
{
if (SeleniumExecutionTerminateFlag)
{
SeleniumQuit();
}
}
[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.TestCase", "http://tfsserver:8080/tfs/PoL;project", "1320", DataAccessMethod.Sequential)]
public void UCP002_M1()
{
var userName = this.TestContext.DataRow["UserName"].ToString();
var passWord = this.TestContext.DataRow["PassWord"].ToString();
//use the local host adress for your project here->
baseURL = this.TestContext.DataRow["URL"].ToString();
driver.Navigate().GoToUrl(baseURL);
//driver.FindElement(By.XPath("//html/body/div[2]/div/a/p/desc")).Click();
//driver.FindElement(By.Id("registerLink")).Click();
driver.FindElement(By.Id("ctl00_LoginTextBox")).Clear();
driver.FindElement(By.Id("ctl00_LoginTextBox")).SendKeys(userName);
driver.FindElement(By.Id("ctl00_PasswordTextbox")).Clear();
driver.FindElement(By.Id("ctl00_PasswordTextbox")).SendKeys(passWord);
driver.FindElement(By.Id("ctl00_LogInButton")).Click();
}
}
Test02.cs
[TestClass]
public class Test02 : SeleniumTestInitialize
{
[TestInitialize]
public void Setup()
{
SeleniumExecutionTerminateFlag = false;
if (!SeleniumInitalizeCheck())
{
SeleniumSetup();
}
}
[TestCleanup]
public void TearDown()
{
if (SeleniumExecutionTerminateFlag)
{
SeleniumQuit();
}
}
[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.TestCase", "http://tfsserver:8080/tfs/PoL;project", "1320", DataAccessMethod.Sequential)]
public void Test02()
{
//some test script
}
}
I have created an ordered test and prioritized the tests in the order of execution . But it is invoking two instances of the driver that means two times the browser.
My question is to How to share a single driver object across all selenium unit tests ?? create at the start and close the driver at the end.
Thanks.
HI If you are using using NUnit.Framework;
The code Execution plan is like below.
For First Test Case
[TestFixtureSetup] ---->For each test case this will work so here we can
initialize the driver instance.
[TestMethod] ----->test method will goes here
[TearDown] -----> clean up code
**For Second Test Case**
[TestFixtureSetup]
[TestMethod]
[TearDown]
If you have to run both test case in one browser instance
Dont close the driver inside TearDown.
AND INITIALIZE THE DRIVER UNDER TextFixtureSetup
[TestFixture()]
public class TestClass
{
[TestFixtureSetUp]
public void Init()
{
Driver.initialize(new InternetExplorerDriver());
}
[TearDown]
public void Close()
{
//dont do any driver.close()
}
[TestMethod]
public void TestCase001()
{
//your code goes here
}
[TestMethod]
public void TestCase002()
{
//your code goes here
}
You can take a look on this thread, where I answered how I did it: How to run multiple test methods in same browser instance without closing it (C#, SeleniumWebDriverz NUnit)?
Basically, I used:
using Microsoft.VisualStudio.TestTools.UnitTesting;
Instead of:
using NUnit.Framework;
So now I have next hierarchy:
[TestFixture]
[TestFixtureSetup] // this is where I initialize my WebDriver " new FirefoxDriver(); "
[Test] //first test
[Test] //second test
[Test] //third test
[TestFixtureTearDown] // this is where I close my driver
With this changes, my browser will open only once for TestFixture (or TestClass if you use "using Microsoft.VisualStudio.TestTools.UnitTesting;") and all [Test]-s from that fixture will run in that same browser instance. After all tests are done, browser will close.
Hope this will help someone else in future. Ask me if you need additional help.
I used NUnit Framework:
using NUnit.Framework;
I then set up my WebDriver initialisation, test and teardown like this:
[TestFixture()]
class NUnitSeleniumTests
{
[OneTimeSetUp]
public void Init()
{
driverIE = new InternetExplorerDriver(ConfigurationManager.AppSettings["IEDriver"]);
driverIE.Manage().Window.Maximize();
// other setup logic
}
[Test]
public void TestMethod1()
{
// Test logic
}
[Test]
public void TestMethod2()
{
// Test logic
}
...
...
...
[Test]
public void TestMethodN()
{
// Test logic
}
[OneTimeTearDown]
public void Close()
{
driverIE.Close();
}
}
When I Run All tests, the WebDriver driverIE is initialised. All tests then execute in that WebDriver instance before the WebDriver instance is closed at the end of the test run.
The tests execute in alphabetical order by default; each test can also execute in isolation.
I am writing NUnit testing code for my WPF C# application. Here some of my methods having MessageBox.Show("");, but we dont know how to handle this in code.
Please help me by providing a solution.
Thanks,
You could create a kind of MessageBoxService that you could Mock in your test. An example code is:
public class ClassUnderTest
{
public IMessageBoxService MessageBoxService { get; set; }
public void SomeMethod()
{
//Some logic
MessageBoxService.Show("message");
//Some more logic
}
}
interface IMessageBoxService
{
void Show(string message);
}
public class MessageBoxService : IMessageBoxService
{
public void Show(string message)
{
MessageBox.Show("");
}
}
Then in your test you could choose to mock the public property or create the constructor to pass the mocked instance.
For example if you use Moq the test could look like this:
[Test]
public void ClassUnderTest_SomeMethod_ExpectsSomtething()
{
ClassUnderTest testClass = new ClassUnderTest();
testClass.MessageBoxService = new Mock<IMessageBoxService>().Object;
//More setup
//Action
//Assertion
}
I'm using NUnit to test my application, which I've included a simplified version of below. I'm looking for a way to fire an event on a mock class, and check that the class under test has received it.
The application calls LogIn on the session, and, some time later, the session fires the OnLoggedIn event. I've set up a mock session, and checked that the app calls LogIn on it. Now I want to fire the OnLoggedIn event on it, and check that the app handles this event.
How can I do this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using NUnit.Mocks;
namespace NUnitTest
{
public delegate void LoggedInDelegate();
public interface ISession
{
void LogIn(String username, String password);
event LoggedInDelegate OnLoggedIn;
}
public class App
{
private bool loggedIn = false;
private ISession sess;
public bool LoggedIn
{
get
{
return loggedIn;
}
}
public App(ISession sess)
{
this.sess = sess;
sess.OnLoggedIn += HandleOnLoggedIn;
}
public void LogIn(String username, String password)
{
sess.LogIn(username, password);
}
public void HandleOnLoggedIn()
{
loggedIn = true;
}
}
[TestFixture]
public class AppTest
{
private String USERNAME = "Username";
private String PASSWORD = "Password";
private DynamicMock mockSess;
private App app;
[SetUp]
public void TestInit()
{
// Create objects.
mockSess = new DynamicMock(typeof(ISession));
app = new App((ISession) mockSess.MockInstance);
}
[Test]
public void TestLogin()
{
mockSess.Expect("LogIn", USERNAME, PASSWORD);
app.LogIn(USERNAME, PASSWORD);
mockSess.Verify();
mockSess.Call("OnLoggedIn");
Assert.IsTrue(app.LoggedIn);
}
}
}
Try this article: https://web.archive.org/web/20110914180329/http://blog.gravityfree.ca/2007/03/raising-events-in-nmock-20.html. I didn't really get it, but I will sit down and try it out later, because I have the same problem.
I usually make an oldfashioned stub object (no mocking framework), and raise the event via a Method call in the stub. It goes something like this:
[TestFixture]
public sealed class TestStubbingEvents
{
[Test]
public void FooReceivesEventFromBar()
{
BarStub bar = new BarStub();
Foo foo = new Foo(bar);
Assert.That(foo.EventReceived, Is.False);
bar.RaiseBarEvent();
Assert.That(foo.EventReceived, Is.True);
}
}
internal class Foo
{
public bool EventReceived
{
get; set;
}
public Foo(IBar bar)
{
EventReceived = false;
bar.BarEvent += ReceiveBarEvent;
}
private void ReceiveBarEvent(object sender, EventArgs args)
{
EventReceived = true;
}
}
internal class BarStub : IBar
{
public event BarEventHandler BarEvent;
//Stub method that invokes the event
public void RaiseBarEvent()
{
BarEvent.Invoke(this, new EventArgs());
}
}
public delegate void BarEventHandler(object sender, EventArgs args);
public interface IBar
{
event BarEventHandler BarEvent;
}
This is the best I've come up with, so I am interested to see what the article in the link can produce.
Added:
Note, that the EventReceived property on the Foo class is just an example on how the event affects the object.