Issue: "The CurrentThread needs to have it's ApartmentState set to ApartmentState.STA to be able to automate Internet Explorer."
First of all i have read all the solutions to the problems above and none works for me.May be i am missing something. I have tried adding Execution Thread entry into my app.config, also tried setting STAThread attribute and i am still facing the same exception as stated above.
Tools: Visual Studio 2010, Watin 2.1, c#
Scenario: Trying to run a unit test [watin script in c#] from a web application upon a button click. But the above exception is thrown when the script is about to launch IE on the following line :
IE mybrowser = new IE ("SomeURL here");
Any Thoughts ?
Got it from a friend. We actually dont have to add any app.config entry. Just start the thread in a single state. In my case, i wrote the following code in my button click handler:
System.Threading.Thread th = new Thread(new ThreadStart(Test));
th.SetApartmentState(ApartmentState.STA);
th.Start();
th.Join();
and i moved the call to unit test in the private. TEST method as follows:
private void Test()
{
var som = new Project.ClassName();
som.MethodToExecute();
}
What does your App.Config look like?
<NUnit>
<TestRunner>
<!-- Valid values are STA,MTA. Others ignored. -->
<add key="ApartmentState" value="STA"/>
</TestRunner>
</NUnit>
The above works for me on Win7, IE9 (32bit), and Watin2.1. It also works on WinXP, IE8, WatiN 2.1. I'm 99% sure it worked just fine on previous versions of WatiN as well. No other ApartmentState changes were needed.
Simply add [assembly: RequiresSTA] at the top of your file or at the entry point of your project.
I had already done the app.config changes
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="NUnit">
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler" />
</sectionGroup>
</configSections>
<NUnit>
<TestRunner>
<add key="ApartmentState" value="STA" />
</TestRunner>
</NUnit>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.3.13283" newVersion="2.6.3.13283" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
but no dice. I opened AssemblyInfo and added
[assembly: RequiresSTA]
and suddenly, the universe began to function properly again.
Related
i'm trying to be adventurous and im trying to get 100% code coverage on my personal project. and i cant the documentation that explains how to simulate a click event using jest, enzyme and react-native.
<Screen.TopBar>
<Toolbar
leftElement="arrow-back"
onLeftElementPress={() => router.pop()}
centerElement={pageName}
/>
</Screen.TopBar>
this is just the top part of it, but im trying to simulate a click on that element.
const wrapper = mount(
<MockProvider store={store}>
<ThemeProvider uiTheme={uiTheme}>
<Category />
</ThemeProvider>
</MockProvider>
);
expect(wrapper.find('Toolbar').length).toBe(1);
i get an error:
ReferenceError: document is not defined
at Object.renderIntoDocument (node_modules/react-dom/lib/ReactTestUtils.js:73:15)
at renderWithOptions (node_modules/enzyme/build/react-compat.js:187:26)
at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:94:59)
at mount (node_modules/enzyme/build/mount.js:19:10)
at Object.<anonymous> (app/screens/category/tests/Category.test.js:32:30)
so my question is how do i select the toolbar so that i can click on the button in the Toolbar component.
Mount only works for react-dom and not for react-native.
I need several profiles for deployment. In the Maven POM I have defined a profile "dev" and a property "theHost" (as localhost):
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault> <!-- use dev profile by default -->
</activation>
<build>
</build>
<properties>
<theHost>localhost</theHost>
</properties>
</profile>
...
I have activated filterDeploymentDescriptor on the maven-ejb-plugin in order to tell it to filter (substitute) values in ejb-jar.xml:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.3</version>
<configuration>
<ejbVersion>3.1</ejbVersion>
--> <filterDeploymentDescriptor>true</filterDeploymentDescriptor>
</configuration>
</plugin
Finally, in ejb-jar.xml I refer to ${theHost} to obtain the desired profile-specific value for the #Resource attribute "host":
<session>
<ejb-name>MongoDao</ejb-name>
<ejb-class>com.coolcorp.MongoDao</ejb-class>
<session-type>Stateless</session-type>
<env-entry>
<env-entry-name>host</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>${theHost}</env-entry-value>
</env-entry>
...
This all works great with a regular Maven build. But when I run an EJB unit test using the Embedded Enterprise Bean Container of GlassFish [EJBContainer.createEJBContainer()], the maven-ejb-plugin seems to ignore filterDeploymentDescriptor=true. The EJB sees "${theHost}" instead of "localhost" although I run maven with the same "dev" profile.
mvn.bat -Pdev test
Does anybody have an idea why the substitution does not work when running a unit test? Is there something more I have to define especially for the unit test so that filtering of ejb-jar.xml occurs? Or a better approach to unit testing EJBs if different profiles exist?
Ideally, you would be able to specify an external "binding" for the env-entry. I know that's possible to do with WebSphere Application Server (via EnvEntry.Value properties), but I don't know if it's possible with Glassfish.
As a workaround, you could declare the env-entry for injection, and then check in PostConstruct whether any value was injected by the container (i.e., don't specify env-entry-value until you're deploying into the server). If you're using JNDI only, you can do the same thing with try/catch(NameNotFoundException).
#Resource(name="host")
private String host;
#PostConstruct
public void postConstruct() {
if (host == null) {
// Not configured at deployment time.
host = System.getProperty("test.host");
}
}
Workaround based on bkail's suggestion: Set a system property only for unit tests and discover it in postConstruct:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14.1</version>
<configuration>
<skip>false</skip>
<argLine>-Xmx1g -XX:MaxPermSize=128m</argLine>
<reuseForks>false</reuseForks> <!-- with reuse the EJB timer service would fail -->
<systemPropertyVariables>
<is.unittest>true</is.unittest>
</systemPropertyVariables>
</configuration>
</plugin>
And then in the Java method annotated with #PostConstruct:
// Override values that were not substituted in ejb-jar.xml
if (Boolean.getBoolean("is.unittest")) {
host = "localhost";
port = "27017";
authenticationRequired = false;
}
When I switch off haltonfailure or haltonerror in my jmunit tests like this:
<jmunit haltonerror="false" haltonfailure="false" failureproperty="testfailure">
<formatter type="xml" />
<classpath>
<path path="${jar_location}" />
<path path="${build}" />
</classpath>
<!-- Add -->
<test name="com.example.tests.Test1" todir="${reports}" />
<test name="com.example.tests.Test2" todir="${reports}" />
<test name="com.example.tests.Etc" todir="${reports}" />
</jmunit >
The build succeeds even when some tests failed. If I turn the halts on, then of course it halts immediately upon the first failure. The behaviour I want is that all tests are executed regardless of how many of them fail, but if ANY of them failed then the build won't be successful. The reason I want this is so that the reports can correctly show how many passes and failures, and which tests are failing.
How do I achieve this?
and/or
Is my thinking that I want all of the tests to be run flawed?
Easy peasy:
You need to add the command
<fail message="Something went wrong. Please check the test results." if="testfailure" />
to the target that contains your jmunit command after the jmunit command itself.
This way, the jmunit task will set the variable testfailure when one of the tests fails and the command fail will make the build unsuccessful if that property is set.
Hope that helps.
I am currently working on an inherited codebase. One of the critical missing pieces is unit testing. I seem to have run into a roadblock while trying to set up some unit tests in NUnit.
I created a separate unit testing project as normal, added the necessary references to SubSonic, NUnit and the various DLLs created by the application and set up a dummy unit test to ensure everything is set up correctly. The problems started when I attempted to reference some of the objects generated by SubSonic. I created this test to list users:
[Test]
public void CanListUsers()
{
UserCollection users = UserController.List(UserController
.Query()
.Where(User.Columns.IsDeleted, false));
Assert.IsNotNull(users);
}
and got this exception:
Can't find the SubSonicService in your
application's config
I fixed that by pulling out the parts of the Web.config that were related to SubSonic into an App.config in the unit testing project. Now, when I rerun the unit tests, I get:
UnitTests.TestClass.CanListUsers:
System.Reflection.TargetInvocationException
: Exception has been thrown by the
target of an invocation. ---->
System.Configuration.ConfigurationErrorsException
: Could not load type
'Utility.SqlSubsonicProvider' from
assembly 'System.Web, Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a'.
This exception has me confused because SqlSubsonicProvider is a class in the Utility namespace and can be seen in Object Browser so why is it being looked for in System.Web?
Edit: Okay, I have rearranged the namespaces in the solution so that they make more sense. I think that fixed the above error. Unfortunately I'm now getting this error:
ChannelMechanics.UnitTests.TestClass.CanListVendors:
System.Reflection.TargetInvocationException : Exception has been thrown by the target
of an invocation.
----> System.NullReferenceException : Object reference not set to an instance of
an object.
What's even stranger is that the unit test passes when I use Visual Studio's "Attach to Process" command in the Debug menu and attach to the NUnit GUI. My theory was that the null object would be easily spotted from within the debugger.
If it helps, my App.config looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="SubSonicService"
type="SubSonic.SubSonicSection, SubSonic"
requirePermission="false"/>
</configSections>
<connectionStrings>
<add name="DatabaseConnection"
connectionString="*removed*"/>
</connectionStrings>
<SubSonicService defaultProvider="TestProvider">
<providers>
<clear />
<add name="TestProvider"
type="SubSonic.SqlDataProvider, SubSonic"
connectionStringName="DatabaseConnection"
generatedNamespace="Test"/>
</providers>
</SubSonicService>
</configuration>
The exception details are:
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type,
Boolean publicOnly, Boolean noCheck, Boolean& canBeCached,
RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis,
Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly,
Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance[T]()
at SubSonic.ActiveController`2.Query()
at UnitTests.TestClass.CanListVendors() in UnitTests\TestClass.cs:line 59
--NullReferenceException
at DataAccess.Vendor.GetTableSchema() in DataAccess\Generated\Models\Vendor.cs:line 376
at DataAccess.Vendor.SetSQLProps() in DataAccess\Generated\Models\Vendor.cs:line 42
at DataAccess.Vendor..ctor() in DataAccess\Generated\Models\Vendor.cs:line 35
The test that I am running is basically the same as the one listed above except it's Vendors rather than Users that should be getting listed.
[Test]
public void CanListVendors()
{
VendorCollection vendors = VendorController.List(
VendorController
.Query()
.Where(Vendor.Columns.IsDeleted, false));
Assert.IsNotNull(vendors);
}
I would suggest there is a System.Web.Utility namespace, and you get this wrong error message because the compiler "thinks" he has to look inside this namespace for resolving the class.
Please check that your test project is set to target framework "Framework 4" and not "Framework 4 Client Profile".
Missing ".NET Framework 4 Client Profile" as target framework in "New Project" window
This seems to be working now. The only change I made within the project was to create a separate test project using Visual Studio's unit test capabilities. The only other explanation I can think of is that something troublesome got thrown out of memory when I rebooted the computer between yesterday evening and today.
For the benefit of anyone stumbling on this question in the future, here is a summary of the steps I took to get NUnit testing a DAL generated by SubSonic:
Create new class library project.
Add necessary references - I added the DAL, NUnit and SubSonic.
Add an App.config file so that
SubSonic knows where to find the
SubSonic service. All I did for this
was to pull out the parts in
Web.config that were related to
SubSonic.
Add a test class and start adding tests to it.
If your tests are inexplicably failing, make sure the "Copy to Output Directory" is set to "Copy if newer" for the App.config that was added, make sure the provider name in App.config matches the provider name used in the DAL classes and, if all else fails, reboot!
Do you always have SubSonic not Subsonic?
This is the relevant section from my nunit projects config file which works...
<configSections>
<section name="SubSonicService"
type="SubSonic.SubSonicSection, SubSonic"
requirePermission="false"/>
</configSections>
<SubSonicService defaultProvider="TAProvider">
<providers>
<clear />
<add name="TAProvider"
type="SubSonic.SqlDataProvider, SubSonic"
connectionStringName="TATesting"
generatedNamespace="DALTA"/>
</providers>
</SubSonicService>
The solution for this error has escaped me for several days now, and it is time to come here for help. The short version is, I have a unit test that fails on the build server but no other environment.
The method I'm testing is an extension method for ILog in log4net. The purpose of this extension method is to make a debug log of the current method, when called and I use it for debugging. The code to do this is pretty straight forward.
public static void MethodHead(this ILog log, params object[] parameters)
{
/* Assert */
log.AssertNonNull();
/* Since this is an expensive operation, don't do it if Debug is not enabled */
if (log.IsDebugEnabled)
{
StackTrace stackTrace = new StackTrace();
/* Get calling method */
MethodBase method = stackTrace.GetFrame(1).GetMethod();
string logMessage = string.Format("{0}.{1}({2})", method.DeclaringType.Name, method.Name, parameters.ToDelimitedString(", "));
log.Debug(logMessage);
}
}
In this method I check that debug mode is enabled, because I don't want to do StackTrace if nothing is supposed to get logged (because of performance issues). When I test this method I will use Rhino Mocks to mock the ILog interface and let IsDebugEnabled return true.
Please consider following NUnit test method.
[Test(Description = "Verify that MethodHead extension method will log with calling class.method(arguments)")]
public void MethodHeadShouldLogCurrentMethodNameWithArguments()
{
/* Setup */
MockRepository mocks = new MockRepository();
ILog log = mocks.CreateMock<ILog>();
string[] arguments = new string[] { "CAT", "IN", "A", "HAT" };
string logMessage = string.Format("{0}.{1}({2})",
"MethodHeadTest", "CallingMethod", arguments.ToDelimitedString(", "));
With.Mocks(mocks).Expecting(delegate
{
/* Record */
Expect.Call(log.IsDebugEnabled).Return(true);
Expect.Call(delegate { log.Debug(logMessage); });
})
.Verify(delegate
{
/* Verify */
CallingMethod(log, arguments);
});
}
private void CallingMethod(ILog log, params object[] arguments)
{
log.MethodHead(arguments);
}
This executes well in my development environment, Visual Studio 2008 with TestDriven.NET. It does execute well if I run the test through nunit-console.exe or nunit-gui. It even runs well if I use my NAnt script to execute the test.
However, my build server fails this test when it runs through NAnt which is executed from CruiseControl.NET. When I run it manually with nunit-console.exe on the build server it succeeds.
The error and stack trace are the following.
Rhino.Mocks.Exceptions.ExpectationViolationException : ILog.Debug("**<>c__DisplayClass8.<MethodHeadShouldLogCurrentMethodNameWithArguments>b__5**(CAT, IN, A, HAT)"); Expected #0, Actual #1.
ILog.Debug("MethodHeadTest.CallingMethod(CAT, IN, A, HAT)"); Expected #1, Actual #0.
at Rhino.Mocks.MethodRecorders.UnorderedMethodRecorder.DoGetRecordedExpectation(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
at Rhino.Mocks.MethodRecorders.MethodRecorderBase.GetRecordedExpectation(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.ReplayMockState.DoMethodCall(IInvocation invocation, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.ReplayMockState.MethodCall(IInvocation invocation, MethodInfo method, Object[] args)
at Rhino.Mocks.MockRepository.MethodCall(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.RhinoInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at ILogProxy86e676a4761d4509b43a354c1aba33ed.Debug(Object message)
at Vanilla.Extensions.LogExtensions.MethodHead(ILog log, Object[] parameters) in d:\Build\Mint\WorkingDirectory\Source\Main\Vanilla\Extensions\LogExtensions.cs:line 42
at Vanilla.UnitTests.Extensions.LogExtensions.MethodHeadTest.<>c__DisplayClass8.<MethodHeadShouldLogCurrentMethodNameWithArguments>b__5() in d:\Build\Mint\WorkingDirectory\Source\Test\Vanilla.UnitTests\Extensions\LogExtensions\MethodHeadTest.cs:line 99
at Rhino.Mocks.With.FluentMocker.Verify(Proc methodCallsToBeVerified)
at Vanilla.UnitTests.Extensions.LogExtensions.MethodHeadTest.MethodHeadShouldLogCurrentMethodNameWithArguments() in d:\Build\Mint\WorkingDirectory\Source\Test\Vanilla.UnitTests\Extensions\LogExtensions\MethodHeadTest.cs:line 90
So the problem is that the build server thinks that this method has another (dynamic?) name. Or rather it is Rhino Mocks that makes this assumption?
I don't get anywhere with this error since I can't recreate it on my development machine. I'm happy for all input I can get.
Thank you!
Mikael Lundin
Looks like CallingMethod was optimized away on the build server. When you repeated the test manually, did you really use exactly the same assembly?
That CallingMethod might get optimized away, is something that I did not think of. Let me run a few more tests on this.
First I invoke nant manually on the build server.
"C:\Program Files\nant-0.86-beta1\bin\nant.exe" test -D:nunit.exe.path="C:\\Program Files\\NUnit 2.4.8\bin\\" -D:Artifact.Output.Path="D:\\Build\\Mint\\Artifacts\\" -D:msbuild.logger="C:\\Program Files\\CruiseControl.NET\\server\\ThoughtWorks.CruiseControl.MSBuild.dll" -D:fxcop.exe.path="C:\\Program Files\\Microsoft FxCop 1.36\\"
This works fine and the test does not fail! I go to the produced binary and execute NUnit manually on it.
D:\Build\Mint\WorkingDirectory\Source\Test\Vanilla.UnitTests\bin\Debug>"C:\Program Files\NUnit 2.4.8\bin\nunit-console.exe" Vanilla.UnitTests.dll
NUnit version 2.4.8
Copyright (C) 2002-2007 Charlie Poole.
Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.
Copyright (C) 2000-2002 Philip Craig.
All Rights Reserved.
Runtime Environment -
OS Version: Microsoft Windows NT 5.2.3790 Service Pack 2
CLR Version: 2.0.50727.3082 ( Net 2.0.50727.3082 )
..............................................................
Tests run: 62, Failures: 0, Not run: 0, Time: 7.891 seconds
And it works as it should. But when I force a build through CC.NET the test fails like I've shown above. Then if I pick the binaries produced by the build server and run NUnit on those I'm back at success.
So, the binaries does't change, but the test succeeds/fails depending on if NAnt is run through command line or CC.NET.
This is the cc.net task I use to execute my NAnt build script.
<nant>
<executable>C:\Program Files\nant-0.86-beta1\bin\nant.exe</executable>
<buildArgs>-D:nunit.exe.path="C:\\Program Files\\NUnit 2.4.8\bin\\" -D:Artifact.Output.Path="D:\\Build\\Mint\\Artifacts\\" -D:msbuild.logger="C:\\Program Files\\CruiseControl.NET\\server\\ThoughtWorks.CruiseControl.MSBuild.dll" -D:fxcop.exe.path="C:\\Program Files\\Microsoft FxCop 1.36\\"</buildArgs>
<nologo>true</nologo>
<buildFile>Mint.build</buildFile>
<targetList>
<target>clean</target>
<target>build</target>
<target>test</target>
<target>staticAnalysis</target>
</targetList>
<buildTimeoutSeconds>1200</buildTimeoutSeconds>
</nant>
The task to execute NUnit in my build script is a bit messier.
<!-- Run all tests -->
<target name="test" description="Run NUnit tests" depends="build">
<property name="Failed.Test.Count" value="0"/>
<!-- Test Vanilla -->
<property name="Test.Name" value="Vanilla.UnitTests" />
<call target="runCurrentTest" />
<fail if="${int::parse(Failed.Test.Count)>0}" message="Failures reported in unit tests" />
</target>
<!-- Utility method to run tests -->
<target name="runCurrentTest">
<exec program="${nunit.exe.path}nunit-console.exe"
failonerror="false"
resultproperty="Test.Result"
verbose="true">
<arg value="${Test.Path + Test.Name + '\bin\Debug\' + Test.Name}.dll" />
<arg value="/xml:${Artifact.Output.Path + Test.Name}-nunit-results.xml" />
<arg value="/nologo" />
</exec>
<property name="Failed.Test.Count" value="${int::parse(Test.Result) + int::parse(Failed.Test.Count)}"/>
</target>
Can I explicitly put optimization flag on the msbuild exec call, to determine that it is not a problem like that? I do point the compilation directly to the csproj file. Shouldn't msbuild pick the optimize configuration from there?
Thank you for all your input!
Mikael Lundin
I solved it.
Removed the CallingMethod from my code and let the tests call the SUT directly. It makes the test code look a bit uglier, but it works.
Still don't know why CallingMethod changed its name when running through CC.NET. I guess that will be for someone else to figure out.