Selenium NUnit run from Main() or exe - selenium-webdriver

I want to run all selenium tests from an exe. I tried the solution mentioned on this thread (Run NUnit test fixture programmatically)
This is what I have written
public class Runner{
public static int Main(string[] args)
{
return new AutoRun(Assembly.GetCallingAssembly())
.Execute(new String[]{"/test:Runner.Foo.Login" });}
[TestFixture]
public class Foo
{
IWebDriver driver;
[Test]
public void Initialize()
{
driver = new FirefoxDriver();// (#"C:\Selenium\Firefox");
driver.Manage().Window.Maximize();
driver.Manage().Timeouts().ImplicitWait =
TimeSpan.FromSeconds(10);
Console.WriteLine("Setup Browser");
}
[Test]
public void Login()
{
eWb.Classes.LoginUser.eWbLogin(driver, ConfigurationSettings.AppSettings["UserId"],
ConfigurationSettings.AppSettings["Password"], "CU");
}}}}
The Console opens and is not able to read the test method Login.

You are passing Assembly.GetCallingAssemby() as a constructor argument to AutoRun. Since this is in your Main, there is no calling assembly, so I assume the value passed is null. Being told to find tests in null, AutoRun is pretty much guaranteed not to find any.
The proper call is to pass no argument at all, since the tests are, in fact, in the assembly making the call. AutoRun itself will figure out what the calling assembly is and should find your tests.
The SO answer to which you list does not use GetCallingAssembly. It uses GetExecutingAssembly. However, since no argument works equally well, that's what I would use. In fact, with NUnit, you should generally use defaults first and only tailor arguments where it's necessary.
Suggest reading the documentation as well: https://github.com/nunit/docs/wiki

Related

Can I create an ambient transaction for testing?

My current system has a rather aggressive data layer that creates an SqlDatabase instance for me by calling a static method. I pass in a stored procedure name (string) and the magic just happens.
I want to try and get some of this crazy system under test and so want to control what is in the database.
Having realised that this structure
[Test]
public void Should_do_some_thing()
{
using (var scope = new TransactionScope())
{
CleanUpDatabase();
SetupDatabaseData();
//Run Test
Assert.That(someResult,Is.EqualTo("ExpectedValue");
scope.Dispose();
}
}
does what I want (no database changes persist outside the test) It would clearly be nicer if I could set up the transaction within a [SetUp] method and remove without committing in the [TearDown] section.
Is this possible?
Note I cannot call any methods on a command object or whatever...
You could use TestInitialize and TestCleanup to do the set up/clean up:
private TransactionScope scope;
[TestInitialize]
public void TestInitialize()
{
scope = new TransactionScope();
CleanUpDatabase();
SetupDatabaseData();
}
[Test]
public void Should_do_some_thing()
{
//Run Test
Assert.That(someResult,Is.EqualTo("ExpectedValue");
}
[TestCleanup]
public void CleanUp()
{
scope.Dispose();
}
You may need to add error handling etc but this is the basics of it:
TestInitialize:
Identifies the method to run before the test to allocate and configure resources needed by all tests in the test class. This class cannot be inherited.
TestCleanUp:
Identifies a method that contains code that must be used after the test has run and to free resources obtained by all the tests in the test class. This class cannot be inherited.
If you are using NUNIT then you can use [SetUp] and [TearDown] instead of [TestInitialize] and [TestCleanUp] respectively.

Mocking a final method with PowerMock + EasyMock

I'm trying to mock a call to the final method ResourceBundle.getString(). With PowerMock 1.4.12 and EasyMock 3.1, the call is not being mocked; instead, the "real" method is called.
My test class:
#RunWith(PowerMockRunner.class)
#PrepareForTest(ResourceBundle.class)
public class TestSuite {
#Before
public void setUp() throws Exception {
ResourceBundle resourceBundleMock = PowerMock.createNiceMock(ResourceBundle.class);
expect(resourceBundleMock.getString(BundleConstants.QUEUE)).andReturn("Queue");
PowerMock.replay(resourceBundleMock);
beanBeingTested.setMessages(resourceBundleMock);
}
...
}
Code in BeanBeingTested:
private ResourceBundle messages;
...
String label = messages.getString(BundleConstants.QUEUE);
Error message:
java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByCGLIB$$e4a02557, key Queue
at java.util.ResourceBundle.getObject(ResourceBundle.java:384)
at java.util.ResourceBundle.getString(ResourceBundle.java:344)
at com.yoyodyne.BeanBeingTested.setUpMenus(BeanBeingTested.java:87)
When I step through the test case, the debugger shows the type of beanBeingTested.messages as "EasyMock for class java.util.ResourceBundle", so the mock is injected correctly. (Also, there's no error on the call to getString() within the expect() call during set up).
With a plain mock instead of a nice mock, I get the following error:
java.lang.AssertionError:
Unexpected method call handleGetObject("Queue"):
getString("Queue"): expected: 1, actual: 0
Any idea what I'm doing wrong?
Thanks.
You are creating an instance using EasyMock. Instead, when working with static methods, you must mock the class (using PowerMock).
It should work like that (tested with EasyMock 3.0 and PowerMock 1.5, though):
#RunWith(PowerMockRunner.class)
#PrepareForTest(ResourceBundle.class)
public class TestSuite {
#Before
public void setUp() throws Exception {
// mock the class for one method only
PowerMock.mockStaticNice(ResourceBundle.class, "getString");
// define mock-behaviour on the class, when calling the static method
expect(ResourceBundle.getString(BundleConstants.QUEUE)).andReturn("Queue");
// start the engine
PowerMock.replayAll();
}
}
(I'm aware this question is a few months old, but it might help others, though)
Try using:
#PrepareForTest({ResourceBundle.class, BeanBeingTested.class})
With only ResourceBundle in the PrepareForTest the mock will work when called directly from your unit test method, but when called from BeanBeingTested you get the real method being used.
Powermock documentation is lacking in this area.
Why bother mocking the call to the resource bundle? Generally, I try to avoid mocking the nuts and bolts of java, such as ArrayList, Date, etc. Resource bundles (and MessageFormat.format()) more or less fall into the same category for me. They generally operate on strings which are fundamentals, and if these things are broken or changing their behavior enough to break a test it's definitely something I want to know :)
Just let them grab the string (which presumably is about to be set in the UI, perhaps after . Don't bother to assert the value returned since you don't want edits to the bundle to break your test. If the string gets set on a mock UI component, This is a good place for anyObject(String.class) which correctly expresses the fact you (probably) don't actually care about the specific string displayed.
I also consider it a benefit when the test fails due to a missing message key. THAT I want to know.

How do I mock a static method that returns void with PowerMock?

I have a few static util methods in my project, some of them just pass or throw an exception. There are a lot of examples out there on how to mock a static method that has a return type other than void. But how can I mock a static method that returns void to just "doNothing()"?
The non-void version uses these lines of code:
#PrepareForTest(StaticResource.class)
...
PowerMockito.mockStatic(StaticResource.class);
...
Mockito.when(StaticResource.getResource("string")).thenReturn("string");
However if applied to a StaticResources that returns void, the compile will complain that when(T) is not applicable for void...
Any ideas?
A workaround would probably be to just have all static methods return some Boolean for success but I dislike workarounds.
You can stub a static void method like this:
PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString());
Although I'm not sure why you would bother, because when you call mockStatic(StaticResource.class) all static methods in StaticResource are by default stubbed
More useful, you can capture the value passed to StaticResource.getResource() like this:
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
PowerMockito.doNothing().when(
StaticResource.class, "getResource", captor.capture());
Then you can evaluate the String that was passed to StaticResource.getResource like this:
String resourceName = captor.getValue();
Since Mockito 3.4.0, an experimental API was introduced to mock static methods.
The following example code has been tested with Mockito 4.3.1 (testImplementation("org.mockito:mockito-inline:4.3.1), and JUnit Jupiter 5.8.2, OpenJDK 11.
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import java.util.UUID;
public class StaticMockTest {
#Test
void showCaseStaticMock() {
try (MockedStatic<StaticMockTest> staticMock = Mockito.mockStatic(StaticMockTest.class)) {
staticMock.when(StaticMockTest::getUUIDValue).thenReturn("Mockito");
Assertions.assertEquals("Mockito", StaticMockTest.getUUIDValue());
}
// Regular UUID
UUID.fromString(StaticMockTest.getUUIDValue());
}
public static String getUUIDValue() {
return UUID.randomUUID().toString();
}
}
Previous Answer, probably Mockito 1.x/2.x with Powermock 1.x/2.x
You can do it the same way you do it with Mockito on real instances. For example you can chain stubs, the following line will make the first call do nothing, then second and future call to getResources will throw the exception :
// the stub of the static method
doNothing().doThrow(Exception.class).when(StaticResource.class);
StaticResource.getResource("string");
// the use of the mocked static code
StaticResource.getResource("string"); // do nothing
StaticResource.getResource("string"); // throw Exception
Thanks to a remark of Matt Lachman, note that if the default answer is not changed at mock creation time, the mock will do nothing by default. Hence writing the following code is equivalent to not writing it.
doNothing().doThrow(Exception.class).when(StaticResource.class);
StaticResource.getResource("string");
Though that being said, it can be interesting for colleagues that will read the test that you expect nothing for this particular code. Of course this can be adapted depending on how is perceived understandability of the test.
By the way, in my humble opinion you should avoid mocking static code if your crafting new code. At Mockito we think it's usually a hint to bad design, it might lead to poorly maintainable code. Though existing legacy code is yet another story.
Generally speaking if you need to mock private or static method, then this method does too much and should be externalized in an object that will be injected in the tested object.
Hope that helps.
Regards
In simpler terms,
Imagine if you want mock below line:
StaticClass.method();
then you write below lines of code to mock:
PowerMockito.mockStatic(StaticClass.class);
PowerMockito.doNothing().when(StaticClass.class);
StaticClass.method();
To mock a static method that return void for e.g. Fileutils.forceMKdir(File file),
Sample code:
File file =PowerMockito.mock(File.class);
PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file);

Problem SilverLight UnitTest Exception, Help!

My Sample Test Class:
namespace Test
{
[TestClass]
public class SampleTest
{
[TestMethod]
public void Test()
{
Assert.IsTrue(true); // <---------- LOOK
}
}
But if i do that:
namespace Test
{
[TestClass]
public class SampleTest
{
[TestMethod]
public void Test()
{
Assert.IsTrue(false); // <---------- LOOK
}
}
i win a AssertFailedException, the test break on this line, however the test dont show failure like a first test do with success!!
Help, ThankĀ“s!!!
My Reference: http://www.jeff.wilcox.name/2008/03/silverlight2-unit-testing/
It's not clear what you are expecting to see and what the problem you are experiencing is.
Based on my deciphering skills, I think you're running into a paradigm difference.
In unit testing, any failed test will often cause a hard error. The reason being that you're not expecting to fail, so when you do, you want attention called to the failure, rather than just a nice test failed message.
Failures are more technically detailed than successes, this is to help you to find the cause of them, like when you see a stack trace and not simply "Error."
Any exception that is not explicitly attended implies (and somewhere should be also written in the output), that the test is failed as you were expecting.

Android Unit Tests Requiring Context

I am writing my first Android database backend and I'm struggling to unit test the creation of my database.
Currently the problem I am encountering is obtaining a valid Context object to pass to my implementation of SQLiteOpenHelper. Is there a way to get a Context object in a class extending TestCase? The solution I have thought of is to instantiate an Activity in the setup method of my TestCase and then assigning the Context of that Activity to a field variable which my test methods can access...but it seems like there should be an easier way.
You can use InstrumentationRegistry methods to get a Context:
InstrumentationRegistry.getTargetContext() - provides the application Context of the target application.
InstrumentationRegistry.getContext() - provides the Context of this Instrumentationā€™s package.
For AndroidX use InstrumentationRegistry.getInstrumentation().getTargetContext() or InstrumentationRegistry.getInstrumentation().getContext().
New API for AndroidX:
ApplicationProvider.getApplicationContext()
You might try switching to AndroidTestCase. From looking at the docs, it seems like it should be able to provide you with a valid Context to pass to SQLiteOpenHelper.
Edit:
Keep in mind that you probably have to have your tests setup in an "Android Test Project" in Eclipse, since the tests will try to execute on the emulator (or real device).
Your test is not a Unit test!!!
When you need
Context
Read or Write on storage
Access Network
Or change any config to test your function
You are not writing a unit test.
You need to write your test in androidTest package
Using the AndroidTestCase:getContext() method only gives a stub Context in my experience. For my tests, I'm using an empty activity in my main app and getting the Context via that. Am also extending the test suite class with the ActivityInstrumentationTestCase2 class. Seems to work for me.
public class DatabaseTest extends ActivityInstrumentationTestCase2<EmptyActivity>
EmptyActivity activity;
Context mContext = null;
...
#Before
public void setUp() {
activity = getActivity();
mContext = activity;
}
... //tests to follow
}
What does everyone else do?
You can derive from MockContext and return for example a MockResources on getResources(), a valid ContentResolver on getContentResolver(), etc. That allows, with some pain, some unit tests.
The alternative is to run for example Robolectric which simulates a whole Android OS. Those would be for system tests: It's a lot slower to run.
You should use ApplicationTestCase or ServiceTestCase.
Extending AndroidTestCase and calling AndroidTestCase:getContext() has worked fine for me to get Context for and use it with an SQLiteDatabase.
The only niggle is that the database it creates and/or uses will be the same as the one used by the production application so you will probably want to use a different filename for both
eg.
public static final String NOTES_DB = "notestore.db";
public static final String DEBUG_NOTES_DB = "DEBUG_notestore.db";
First Create Test Class under (androidTest).
Now use following code:
public class YourDBTest extends InstrumentationTestCase {
private DBContracts.DatabaseHelper db;
private RenamingDelegatingContext context;
#Override
public void setUp() throws Exception {
super.setUp();
context = new RenamingDelegatingContext(getInstrumentation().getTargetContext(), "test_");
db = new DBContracts.DatabaseHelper(context);
}
#Override
public void tearDown() throws Exception {
db.close();
super.tearDown();
}
#Test
public void test1() throws Exception {
// here is your context
context = context;
}}
Initialize context like this in your Test File
private val context = mock(Context::class.java)

Resources