I'm trying to create a testNG suite for running tests using Appium concurrently on multiple devices. I'm currently using an #BeforeSuite to setup the server/driver for each device, and then distributing the connections to test methods using #BeforeMethod and #AfterMethod functions. I have a master suite-of-suite .xml that calls down to different child .xml files associated with each of my test classes. The test classes are each associated with a #Factory, which allows me to run the instances in parallel (decided at run-time based on the number of attached devices).
Parent
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Default Suite">
<parameter name="other" value="#SOMETHING#"></parameter>
<suite-files>
<suite-file path="src/first.xml" />
<suite-file path="src/second.xml" />
</suite-files>
</suite>
Child
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="first" parallel="instances">
<test name="android">
<classes>
<class name="TestFactory" />
</classes>
</test>
</suite>
Factory
public class TestFactory {
#Factory
public Object[] initial() {
int numDevices = DeviceManager.getNumAttachedDevices();
Object[] result = new Object[numDevices];
for (int i = 0; i < numDevices; i++) {
result[i] = new StartupTest();
}
return result;
}
}
I definitely don't want to do this. It seems pretty ridiculous that I need to create a new #Factory class for each of the test classes that I want. I found out recently that I can use parallel=true inside of a #DataProvider, which can be used together with paralell="methods" and an annotation transformer for invocationCount in order to achieve a similar result (one method running for each of the attached devices).
I'm not sure how my #BeforeMethod and #AfterMethod calls can be used to do the required setup and cleanup on the correct device (they would be missing the device name). Is there any other recommended way for doing this? Or is this my best option?
It turns out that I can use my #Factory method inside of the test class, instead of making a separate class altogether.
As far as I can tell, it's not simple to control the TestNG threads on parallel="methods" so that they all join after running a single method. Without that capability, it seems a lot more complicated (and not worthwhile) to use #DataProvider.
Inside of my #Factory I can still pass custom arguments for each of the instances.
Related
I am using Spring data jpa for executing native Query, here is the example.
#Query(value = "select name from customer", nativeQuery = true)
public List<String> findNameNative() ;
Now, due to company constraint can't put the entire query here, but query is pretty huge, like 100 lines.
N we have many such queries.
Is there a way i can define queries in a separate file like xml or properties file and refer them here. (to keep the code clean)
Appericiate the help.
Thanks.
After many efforts and tries found the solution.
1) create the xml file (with any name) in resources folder of your project. Say testSQL.xml inside resources /query
2) follow the xml standard of 'orm.xml' in testSQL.xml, this copy paste the header and create the tags of,
<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
version="1.0">
<named-native-query>
</named-native-query>
</entity-mapping>
3) in this xml create the tag with named-native-query tag.
<named-native-query name="XyzEntity.methodName">
<query>
<! [CDATA[
Your native query
] ] >
</query>
</named-native-query>
Note - > multiple such native named query tags can be added and all of them must reside between
<entity-mapping> </entity-mapping>
4) "XyzEntity" mentioned in name tag in above step, should have a Jpa repository and in that repository we should have method with the same name as the tag. I. E.
public interface XyzRepo extends JpaRepository <XyzEntity, Long> {
Tuple methodName() ;
}
5) add the testSQL.xml in application property file as below
spring.jpa.mapping-resources = query/testSQL.xml
N then you can call this method normal spring way.
Kindly let me know if someone is stuck on this and need detail solution.
You can externalize de value, which is the query itself. Inside the src/main/resources, create a folder called META-INF. Inside it, create a file called jpa-named-queries.properties.
Suppose your entity is called Customer and the table is TBL_CUSTOMER.
When you keep the query inside the code, on your repository, you have the code you wrote. You can externalize it this way:
CustomerRepository.java
#Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {
#Query(nativeQuery = true)
public List<String> findNameNative();
}
jpa-named-queries.properties
Customer.findNameNative=\
SELECT C.NAME \
FROM TBL_CUSTOMER C \
WHERE CONDITIONS
Names must match and you must use \ for line breaks.
Under resources create META-INF/jpa-named-queries.properties. In this file define your queries this way:
MyEntity.fetchEntityBySomething=select name from Customer
I have not tried native queries however, usual queries would work this way.
However, check this out: https://github.com/gasparbarancelli/spring-native-query
I think DarkKnight's solution is the best, set entity mappings with xml can take advantage of IDE to have highlight and indentation.
But if you are using spring boot, there will be an optimization.
There is a related spring boot property for it: spring.jpa.mapping-resources, you can set entity mappings path into this property. And this property can be an array, you can set more than one value into it.
Following the procedures outlines here and here I was able to set a TestRunParameter and access it at run time in a Unit test. I then repeated the exact same process in a coded UI test but am not able to access the Properties.
My .runsettings file:
<RunSettings>
<TestRunParameters>
<Parameter name="webAppUrl" value="http://localhost" />
</TestRunParameters>
</RunSettings>
My Test Method:
[TestMethod]
public void MyTest1()
{
// This throws an error because Properties["webAppUrl"] is null
string webAppUrl = TestContext.Properties["webAppUrl"].ToString();
// etc...
}
Does a Coded UI test need additional configuration to access these run time properties?
Edit:
I notice that within the context of a Unit test, the TestContext is Microsoft.VisualStudio.TestPlatform.MSTestFramework.TestContextImplementation. In the Coded UI test, the TestContext is Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapterContext.
The parameters defined in .runsettings TestRunParameter section can't be accessed in Coded UI test. When you debug the Coded UI test, you will find that TextContext.Properties contains some values, ResultsDirectory, AgentId and etc.
However, parameter defined in the TestRunParameter section can't be found.
Instead of setting parameters in TestRunParameter section, you can create a .cvs or .xml file, and access the data via data-driven. Check this article for the details:
https://msdn.microsoft.com/en-us/library/ee624082.aspx
Try Using it in ClassInitialize inplace of Test Method refer below code
[ClassInitialize]
public static void TestClassinitialize(TestContext context)
{
var webAppUrl = context.Properties["webAppUrl"].ToString();
}
I am currently developing a few Web services using the JAX-WS reference implementation (version 2.1.7). They are contract-based, that is, the WSDL and XSD files are not generated by wsgen.
This allows me to freely use XSD restrictions to strengthen validation of values passed to my services through SOAP messages. Here are two examples of such "restricted" XSD elements:
<xsd:element name="maxResults" minOccurs="1">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:minInclusive value="1"/>
<xsd:maxInclusive value="1000"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="lastName" minOccurs="0">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:minLength value="1"/>
<xsd:maxLength value="25"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
I added the #SchemaValidation annotation to my service classes to enforce schema validation. However, JAX-WS does not enforce validation rules as expected. The behaviour is as follows:
Missing mandatory elements are correctly reported (e.g., missing maxResults).
Invalid values (e.g., character data in an integer field) are correctly reported too.
Interval restriction violations (e.g., maxResults > 1000 or maxResults < 1) pass through the validation process without being reported and are injected into my JAXB-generated Java structures. Even negative values are considered valid despite the xsd:positiveInteger type!
String length constraint violations (e.g., lastName length over 25 characters) are not reported either.
In other words, restrictions that appear in <xsd:element> tags are correctly enforced but <xsd:restriction> elements seem to be totally ignored by JAXB when used in a JAX-WS-based context.
I wrote a test class to check my XSD restrictions using bare JAXB (no JAX-WS). As a result, all restrictions are correctly enforced.
This gives me the feeling that there might be a bug in the usage of JAXB by JAX-WS... unless there is something I am doing incorrectly, of course...
Am I missing something fundamental here?!?
Thanks in advance for any help,
Jeff
I finally found what's wrong...
In order to get my Web services to work in a JUnit context, i.e. published through Endpoint.publish(), I had to remove the wsdlLocation attribute from my #WebService annotations. If I don't, the wsdlLocation = "WEB-INF/wsdl/SearchIndividualsV1_0.wsdl" passed to the #WebService annotation clashes with the URL value passed to the Endpoint.publish() method, http://127.0.0.1:9000/rpe-ws/SearchIndividuals.
After reading Glen Mazza's Weblog (http://www.jroller.com/gmazza/entry/soap_xml_schema_validation), Additional Notes section, I put back the wsdlLocation attribute and all restrictions are now properly enforced.
In other words, removing the wsdlLocation in a #WebService annotation does not prevent the service itself from working, but prevents restrictions declared in <xsd:restrictions> elements from being properly enforced. Restrictions declared in <xsd:element> elements, however, are still correctly enforced.
I am therefore getting back to having to solve that wsdlLocation compatibility problem to make my unit tests work properly, but this is way less critical than non-working validations in a production context...
Just in case... Anyone has an idea about this WSDL location incompatibility when running a Web service in a non-Web context?
Thanks,
Jeff
Oh brother!...
In order to override the wsdlLocation for my JUnit tests, I created derivations of my Web service implementations that override only the #WebService annotation. As a result, I ran into the same problem I finally solved this morning (ref. my first answer above).
After doing plenty of tests, I figured out that it's the presence of a #WebService-annotated class extending my Web service implementation that prevents XSD validation from properly handling <xsd:restriction> tags.
To illustrate this bizarre behaviour, let's suppose I have the following classes:
#WebService(...)
public interface JeffWebService {...}
#WebService(..., wsdlLocation = "path/myWsdl.wsdl", ...)
public class JeffWebServiceImpl implements JeffWebService {...}
where path/myWsdl.wsdl correctly locates the WSDL. Then XSD validation works properly, i.e. the content of my first answer above is totally valid.
I now add the following class that I use in my JUnit-based Endpoint.publish() calls:
#WebService(..., wsdlLocation = "alternatePath/myWsdl.wsdl", ...)
public class TestWebServiceImpl extends JeffWebServiceImpl {}
that overrides nothing but the #WebService annotation. Then XSD validation excludes <xsd:restriction> tags as it used to do before specifying the wsdlLocation attribute at all, despite the fact that I still use the JeffWebServiceImpl implementation in my non-JUnit code! If I comment out the annotation in TestWebServiceImpl, then everything works properly again, except for unit tests, of course.
In other words, as soon as there is some class extending my Web service implementation in the classpath, the #WebService annotation of the most specific class overrides all others, regardless of the actual class I use in a regular Web application context. Weird, isn't it?!?
Bottom line: I will disable Endpoint-based unit tests for now. If I (or anyone reading this thread) find a clean, non-bogus way to integrate both production and JUnit configurations, I will consider putting them back in my JUnit test suite.
I hope this thread will help anyone running into the same problem solve it faster than I did...
Jeff
We are in the process of converting existing code to an OSGi environment. In one of our (yet to be) OSGi bundles we have code that perform an XSLT transformation. A piece of the XSLT includes a java extension function to create a unique numeric value. The Java class also resides within the bundle. This is a fragment of the style sheet:
<xsl:template match="m:property">
<xsl:variable name="uniqueDataStreamName" select="concat(../#id,'/',#name)" />
<xsl:variable name="uniqueDataStreamId"
select="java:com.xyz.TransformationUtils.makeDataStreamIdFromUniqueName($uniqueDataStreamName)" />
<data id="{number($uniqueDataStreamId)}">
<tag>
<xsl:value-of select="$uniqueDataStreamName" />
</tag>
<current_value>
<xsl:value-of select="#value" />
</current_value>
</data>
For reference, this is how the transformation is set up and called:
protected Templates createTemplates(Source xsltSource) {
try {
TransformerFactory tf = TransformerFactory.newInstance();
Templates templates = tf.newTemplates(xsltSource);
return templates;
} catch (TransformerException e) {
throw new RuntimeException(e);
}
}
protected byte[] transform(byte[] input) throws TransformerException {
ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
templates.newTransformer().transform(
new StreamSource(new ByteArrayInputStream(input)),
new StreamResult(out));
return out.toByteArray();
}
When run in a non OSGi environemnt, it works. When run in an OSGi framework, it fails because the stylesheet cannot be compiled because the class TransformationUtils cannot be found. I kind of understand that--the class loader loading the jaxp transformer implementation does not see the extension class in our bundle. However, I'm stumped at finding a solution. I've tried using OSGi:fied Xalan and Xerces bundles to no avail.
My question is: How can this be solved? Can it?
The answer depends on how the XSLT processor looks up the extension class. You might need to read the source code and/or run it through a debugger to find this out.
For example, if the XSLT processor uses the Thread Context ClassLoader (TCCL) then this would normally fail because the TCCL is undefined in OSGi. You can work around this by explicitly setting the TCCL for the duration of the call to the XSLT processor, e.g.:
ClassLoader orig = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(MyClass.class.getClassLoader());
try {
// invoke XSLT processor
} finally {
Thread.currentThread.setContextClassLoader(orig);
}
where MyClass is a class from your bundle and has visibility of the extension class.
In the worst case, the processor might look up the extension using its own classloader, i.e. with a simple call to Class.forName(). The best thing to do here is to beat up the developer of the library for being so stupid. After you've done that, you could use a fragment to attach the extension class to the processor bundle... it's a nasty hack but better than some of the other possible nasty hacks.
I have a following object:
public class TestObject
{
public String Something { get; set; }
}
and a following objects file:
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd">
<object id="TestObject" type="SpringTest.TestObject" autowire="byName"/>
</objects>
What I would like to do is to register singleton and get the TestObject. I am doing this like so:
IConfigurableApplicationContext context = new XmlApplicationContext("objects.xml");
context.ObjectFactory.RegisterSingleton("Something", "something to test");
object obj = context.GetObject("TestObject");
But the objects property Something is always null. I think that this should work or am I doing something wrong?
Many thanks!
I'm not sure what the problem statement is exactly (never used Spring for .NET). But if you want what Don Kirkby suggest you should lookup TargetSources in the reference documentation (assuming that the .NET implementation has them, too).
I think your Something property is not getting set because singletons are instantiated when the application context is instantiated. When you call RegisterSingleton, the TestObject has already been created. The bean wiring is only done when a bean is created.
You might be able to work around this problem by making the singleton instantiate lazily. That way it isn't instantiated until the first time it's requested. Hopefully, that's after you've registered the other singletons it needs.
I don't know exactly what you're trying to accomplish, but if I wanted to change the wiring between some singleton beans at run time without making the beans aware of it, I would introduce some wrapper objects. Each wrapper would implement an interface and then just delegate all methods to its current target bean. To change the wiring, you just change the wrapper's target.
Update: as yawn suggested, Spring.NET has hot-swappable target sources that let you swap out the implementation of a bean at run time. Here's some sample code from the documentation that shows how to swap the bean implementation:
HotSwappableTargetSource swapper =
(HotSwappableTargetSource) objectFactory.GetObject("swapper");
object oldTarget = swapper.swap(newTarget);
The XML definitions in the documentation look like this:
<object id="initialTarget" type="MyCompany.OldTarget, MyCompany">
</object>
<object id="swapper"
type="Spring.Aop.Target.HotSwappableTargetSource, Spring.Aop">
<constructor-arg><ref local="initialTarget"/></constructor-arg>
</object>
<object id="swappable"
type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="targetSource">
<ref local="swapper"/>
</property>
</object>
Why aren't you using scope="singleton" if you want a singleton or am I missing something?