Invalid content passes unit test?
I have a unit test for my grammar (following the docs). The test passes with an invalid example; however entering the same example in a runtime instance is handled correctly (i.e. errors shown in the IDE).
Would appreciate any pointers.
Grammar as follows:
grammar spreadsheet.Loader with org.eclipse.xtext.common.Terminals
generate loader "http://www.spreadsheet/Loader"
Specification:
(columns += Column)*;
Column:
'col' name=ID '{'
'header' ':' header=STRING
'type' ':' type=ID
Unit Test:
package spreadsheet.loader.tests
import org.eclipse.xtext.junit4.XtextRunner
import spreadsheet.LoaderInjectorProvider
import org.eclipse.xtext.junit4.InjectWith
import org.junit.runner.RunWith
import com.google.inject.Inject
import org.eclipse.xtext.junit4.util.ParseHelper
import spreadsheet.loader.Specification
import org.junit.Test
import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertNotNull
@InjectWith(LoaderInjectorProvider)
@RunWith(XtextRunner)
class TestGrammar {
@Inject
ParseHelper<Specification> parser
@Test
def void testParseSpecification() {
val spec = parser.parse(
'''col surname foo {
header: "Surname"
type: String bar
assertNotNull(spec)
val col = spec.columns.head
assertEquals("surname", col.name)
[The "foo" and "bar" tokens should cause parsing to fail].
Thanks.
On 04/08/2015 17:36, Scott Finnie wrote:
> I have a unit test for my grammar (following the docs). The test passes
> with an invalid example; however entering the same example in a runtime
> instance is handled correctly (i.e. errors shown in the IDE).
>
> Would appreciate any pointers.
>
> Grammar as follows:
>
> grammar spreadsheet.Loader with org.eclipse.xtext.common.Terminals
>
> generate loader "http://www.spreadsheet/Loader"
>
> Specification:
> (columns += Column)*;
>
> Column:
> 'col' name=ID '{'
> 'header' ':' header=STRING
> 'type' ':' type=ID
> '}'
> ;
>
>
> Unit Test:
>
>
> package spreadsheet.loader.tests
>
> import org.eclipse.xtext.junit4.XtextRunner
> import spreadsheet.LoaderInjectorProvider
> import org.eclipse.xtext.junit4.InjectWith
> import org.junit.runner.RunWith
> import com.google.inject.Inject
> import org.eclipse.xtext.junit4.util.ParseHelper
> import spreadsheet.loader.Specification
> import org.junit.Test
> import static org.junit.Assert.assertEquals
> import static org.junit.Assert.assertNotNull
>
> @InjectWith(LoaderInjectorProvider)
> @RunWith(XtextRunner)
> class TestGrammar {
>
> @Inject
> ParseHelper<Specification> parser
>
> @Test
> def void testParseSpecification() {
> val spec = parser.parse(
> '''col surname foo {
> header: "Surname"
> type: String bar
> }'''
> )
> assertNotNull(spec)
> val col = spec.columns.head
> assertEquals("surname", col.name)
> }
> }
>
>
> [The "foo" and "bar" tokens should cause parsing to fail].
>
> Thanks.
>
Hi
parsing succeeds, and you need to check for errors explicitly: you need a
@Inject extension ValidationTestHelper
and then explicitly check that
for example if you do
spec.assertNoErrors
the test will fail (and show the errors).
You may want to assert a specific error: ValidationTestHelper provides
many assertError methods for that purpose.
hope this helps
Lorenzo
Lorenzo Bettini, PhD in Computer Science, DI, Univ. Torino
HOME: http://www.lorenzobettini.it
Xtext Book:
http://www.packtpub.com/implementing-domain-specific-languages-with-xtext-and-xtend/book
Similar Messages
-
[svn:osmf:] 10137: Dynamic streaming unit tests now pass.
Revision: 10137
Author: [email protected]
Date: 2009-09-10 16:01:37 -0700 (Thu, 10 Sep 2009)
Log Message:
Dynamic streaming unit tests now pass.
Modified Paths:
osmf/trunk/framework/MediaFramework/org/openvideoplayer/net/dynamicstreaming/NetStreamSwi tchableTrait.as
osmf/trunk/framework/MediaFramework/org/openvideoplayer/traits/SwitchableTrait.as
osmf/trunk/framework/MediaFrameworkFlexTest/org/openvideoplayer/MediaFrameworkTests.as
osmf/trunk/framework/MediaFrameworkFlexTest/org/openvideoplayer/traits/TestISwitchable.asHello!
1) Given the string plugin is loaded from (file:///C:/alex/PlayerCDN/lib/PlugIN_junio.swf) application loads it from file system that "involves complex security" (our app can't load local files - we don't need it but nevertheless).
You may want to try directing your Flex builder run configuration to use http://localhost/yourappwrapper.html as a "URL or path to launch" parameter.
Try to set full path to plugin also (including host).
2) As I can see, you don't have
Security.allowDomain('*');
in your plugin constructor.
Although it is being loaded from the same host - do try to insert it
Here is our plugins main file - everything works fine:
package {
import flash.display.Sprite;
import flash.system.Security;
import org.osmf.media.PluginInfo;
import plugin.ControlBarPlugin;
public class CBPlugin extends Sprite
private var _pluginInfo:PluginInfo;
public function CBPlugin()
Security.allowDomain('*');
_pluginInfo = (new ControlBarPlugin).pluginInfo;
public function get pluginInfo():PluginInfo{
return _pluginInfo; -
Unit test runs perfectly fine with NUnit but fails when run from TestExplorer
Hello all,
I have a TestProject, Harmony.Tests. In there, I have a method AddApplicationEvent()
which calls another method Send(InvokeRequestMessage requestMessage) which calls a webservice (OperationHandlerBrokerWebService).
The code snippet looks like this. This is not the complete code but a part where we are calling the web service. It fails on the underlined Italic line of code.
OperationHandlerBrokerWebService brokerService = new OperationHandlerBrokerWebService();
brokerService.UseDefaultCredentials = true;
brokerService.Url = address;
brokerService.Timeout = timeoutInMilliseconds;
byte[] serializedResponseMessage = brokerService.InvokeOperationHandler(serializedRequestMessage);
The same test works and passed fine when I ran it with NUnit, but failed with following exception when I tried to run it from TestExplorer.
Test Name: AddApplicationEvent
Test FullName: N4S.Harmony.Tests.CaseManagement.HarmonyFacadeTests.AddApplicationEvent
Test Source: d:\TFS\TMW\Dev\TMWOnline\Harmony\N4S.Harmony.Tests\CaseManagement\HarmonyFacadeTests.cs : line 665
Test Outcome: Failed
Test Duration: 0:00:00.296
Result Message:
SetUp : Message returned System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: Invalid token for impersonation - it cannot be duplicated.
at System.Security.Principal.WindowsIdentity.CreateFromToken(IntPtr userToken)
at System.Security.Principal.WindowsIdentity..ctor(SerializationInfo info)
at System.Security.Principal.WindowsIdentity..ctor(SerializationInfo info, StreamingContext context)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._SerializationInvoke(Object target, SignatureStruct& declaringTypeSig, SerializationInfo info, StreamingContext context)
at System.Reflection.RuntimeConstructorInfo.SerializationInvoke(Object target, SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
at N4S.Forms.OperationHandlerBroker.AMessage.DeserializeMessage(Byte[] serializedMessage)
at N4S.Forms.OperationHandlerBroker.WebServiceServer.BrokerService.InvokeOperationHandler(Byte[] serializedInvokeRequestMessage)
--- End of inner exception stack trace ---
expected: <0>
but was: <1>
Result StackTrace:
at N4S.Harmony.Tests.TestHelper.InvokeOperation(OperationHandler handler, OperationHandlerInput input, Boolean expectedToWork) in d:\TFS\TMW\Dev\TMWOnline\Harmony\N4S.Harmony.Tests\TestHelper.cs:line 136
at N4S.Harmony.Tests.TestHelper.LoginAsUser(String username, String password) in d:\TFS\TMW\Dev\TMWOnline\Harmony\N4S.Harmony.Tests\TestHelper.cs:line 394
at N4S.Harmony.Tests.TestHelper.Login(TestUserName requestedUser) in d:\TFS\TMW\Dev\TMWOnline\Harmony\N4S.Harmony.Tests\TestHelper.cs:line 377
at N4S.Harmony.Tests.TestHelper.LoginAsAdvisor() in d:\TFS\TMW\Dev\TMWOnline\Harmony\N4S.Harmony.Tests\TestHelper.cs:line 230
at N4S.Harmony.Tests.CaseManagement.HarmonyFacadeTests.Login() in d:\TFS\TMW\Dev\TMWOnline\Harmony\N4S.Harmony.Tests\CaseManagement\HarmonyFacadeTests.cs:line 76
at N4S.Harmony.Tests.CaseManagement.HarmonyFacadeTests.SetupTest() in d:\TFS\TMW\Dev\TMWOnline\Harmony\N4S.Harmony.Tests\CaseManagement\HarmonyFacadeTests.cs:line 67
I am not sure what causing the issue. I checked the Credentials, Windows Identity during both the test run and there is no difference. Please advise !!
Thanks,
DeepakHi Tina,
Thanks for your reply.
I do have NUnit adapter installed. I even noticed that the test runs fine with NUnit GUI and also if I run it through Resharper Test Explorer window.
As you can see in the image above the same test is passed when I ran it from Resharper Unit Test Explorer window but fails when I ran it from Test Explorer window. I also captured the information on fiddler.
There was a significant difference in the Header Content length. Also under the User-Agent property the protocol versions are different.
Not sure why VSTest ExecutionEngine is picking a different version.
The UnitTest in question is calling a webservice method which in turn calls a method from another referenced project.
Web Service class
using System;
using System.Web.Services;
using N4S.Forms.OperationHandlerBroker.Server;
using NLog;
namespace N4S.Forms.OperationHandlerBroker.WebServiceServer
/// <summary>
/// The operaton-handler broker service.
/// </summary>
[WebService(Description = "The N4S Forms Operation-Handler Broker Web-Service.", Name = "OperationHandlerBrokerWebService",
Namespace = "N4S.Forms.OperationHandlerBroker.WebServiceServer")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class BrokerService : WebService
{ /// <summary>
/// Calls <see cref="HandleRequest"/>. Updates performance-counters.
/// </summary>
/// <param name="serializedInvokeRequestMessage">the binary-serialized <see cref="InvokeRequestMessage"/></param>
/// <returns>the binary-serialized response message</returns>
[WebMethod(BufferResponse = true, CacheDuration = 0, Description = "Invokes the requested operation-handler and returns a binary-serialized response-message.", EnableSession = false)]
public byte[] InvokeOperationHandler(byte[] serializedInvokeRequestMessage)
logger.Trace(Strings.TraceMethodEntered);
PerformanceMonitor.RecordRequestStarted();
InvokeRequestMessage requestMessage = (InvokeRequestMessage) AMessage.DeserializeMessage(serializedInvokeRequestMessage);
InvokeResponseMessage responseMessage;
try
responseMessage = HandleRequest(requestMessage);
PerformanceMonitor.RecordSuccessfulRequest();
catch (Exception)
PerformanceMonitor.RecordFailedRequest();
throw;
finally
PerformanceMonitor.RecordRequestEnded();
logger.Trace(Strings.TraceMethodExiting);
return AMessage.SerializeMessage(responseMessage);
UnitTest snippet
OperationHandlerBrokerWebService brokerService = new OperationHandlerBrokerWebService();
brokerService.UseDefaultCredentials = true;
byte[] serializedResponseMessage = brokerService.InvokeOperationHandler(serializedRequestMessage);
Please advise.
Thanks,
Deepak -
Error message: invalid content type for SOAP: TEXT/HTML; HTTP 403 Forbidd
Hi All,
My scenario is Proxy to File
So in-order to test the scenario i am sending the Data from RWB using TestMessage
i have given the sender and receiver details.
and the payload i am passing is
<?xml version="1.0" encoding="UTF-8"?>
<ns0:MT_QAStatusReport xmlns:ns0="http://XXXX.com/xi/SARERP/IF0100_QAStatusReport/100">
<RECORD_STRCUTURE>
<RECORD>
<INSP_LOT>New for EU</INSP_LOT>
<MATNR>00000500418</MATNR>
<SHORT_TEXT> caps SE</SHORT_TEXT>
<PLANT>0082</PLANT>
<BATCH>59756</BATCH>
<VENDOR_BATCH>59756</VENDOR_BATCH>
<INQUAL_INSP>1940</INQUAL_INSP>
<SSQUAL_INSP>0</SSQUAL_INSP>
<VENDOR/>
<DATELOT_CREA>7/20/2011</DATELOT_CREA>
<DAYS_QA>26</DAYS_QA>
<COMMENTS>Pending Import Testing</COMMENTS>
</RECORD>
</RECORD_STRCUTURE>
</ns0:MT_QAStatusReport>
the error i am facing is
Error while sending message: invalid content type for SOAP: TEXT/HTML; HTTP 403 Forbidden
can any one suggest me how to solve the isssue
Thanks&Regards
SaiI had received similar error , request you to also check following,
1. while sending the message from IE placed in RWB, just check the URL in the Test Message tab, its possible that this PI is installed just now and its settings are not done correctly. In this ask the owner or the BASIS to change it to correct URL.
for example it should look something like - http://sdndevdpi001:50100/sap/xi/engine?type=entry -
Invalid content type for SOAP: TEXT/PLAIN; HTTP 200 OK
Hi,
I am working on RFC - XI - WebService scenario. tested web service with soapUI and works fine. but while configured in XI getting below error.
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
- <!-- Inbound Message
-->
- <SAP:Error xmlns:SAP="http://sap.com/xi/XI/Message/30" xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" SOAP:mustUnderstand="1">
<SAP:Category>XIAdapterFramework</SAP:Category>
<SAP:Code area="MESSAGE">GENERAL</SAP:Code>
<SAP:P1 />
<SAP:P2 />
<SAP:P3 />
<SAP:P4 />
<SAP:AdditionalText>com.sap.aii.af.ra.ms.api.DeliveryException: invalid content type for SOAP: TEXT/PLAIN; HTTP 200 OK</SAP:AdditionalText>
<SAP:ApplicationFaultMessage namespace="" />
<SAP:Stack />
<SAP:Retry>M</SAP:Retry>
</SAP:Error>
Thanks,
MaheshHi Stefan,
Imported webservice in external definition and the web service has 3 messages in it.
1. header
2. requestdoc
3. response.
while creating message interface, i can select only one input message (here i have to pass values for both Header & request doc). if i create 2 separate message interfaces one for header & one for requestdoc, how can i add both of them as target messages in meesage mapping? it gives me error if i add multiple target messages because the mode is synchronous.
How do we map when we have multiple messages (header & request) in a web service?
I created a new message type with header & requestdoc in it, and used in mapping. Do you think the above problem is occuring because of this?
My webservice structure looks like below.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<soap:RequestHeader>
<soap:variable1></soap:variable1>
<soap:variable2></soap:variable2>
<soap:variable3></soap:variable3>
</soap:RequestHeader>
</soapenv:Header>
<soapenv:Body>
<soap:SOAPRequest>
<RequestDoc></RequestDoc>
</soap:SOAPRequest>
</soapenv:Body>
</soapenv:Envelope>
Thanks,
Mahesh -
Revision: 14261
Revision: 14261
Author: [email protected]
Date: 2010-02-18 14:15:23 -0800 (Thu, 18 Feb 2010)
Log Message:
Updated DRM unit tests to work with code review feedback.
Modified Paths:
osmf/trunk/framework/OSMFTest/org/osmf/elements/TestParallelElementWithDRMTrait.as
osmf/trunk/framework/OSMFTest/org/osmf/elements/TestSerialElementWithDRMTrait.as
osmf/trunk/framework/OSMFTest/org/osmf/traits/TestDRMTrait.as
osmf/trunk/framework/OSMFTest/org/osmf/utils/DynamicDRMTrait.asHello Alex,
I don't have an answer for you.
But, can you try to use http://drmtest2.adobe.com:8080/Content/anonymous.f4v with locally hosted OSMF player? This content doens't require user/pass info.
I'm wondering that Google TV's flash player doesn't support prompt dialog.
http://drmtest2.adobe.com/AccessPlayer/player.html requires flash player 11. That's why it won't be loaded with flash player 10.x.
Thanks,
-- Hiroshi -
Revision: 11282
Author: [email protected]
Date: 2009-10-29 16:44:46 -0700 (Thu, 29 Oct 2009)
Log Message:
updated the unit tests for the DRM subsystem. Still lacking tests for Authentication Token.
Modified Paths:
osmf/trunk/framework/MediaFramework/.actionScriptProperties
osmf/trunk/framework/MediaFramework/org/osmf/drm/DRMServices.as
osmf/trunk/framework/MediaFramework/org/osmf/net/NetStreamContentProtectableTrait.as
osmf/trunk/framework/MediaFramework/org/osmf/video/VideoElement.as
osmf/trunk/framework/MediaFrameworkAirTest/.actionScriptProperties
osmf/trunk/framework/MediaFrameworkFlexTest/.actionScriptProperties
osmf/trunk/framework/MediaFrameworkFlexTest/.flexProperties
osmf/trunk/framework/MediaFrameworkFlexTest/org/osmf/traits/TestIContentProtectable.as
osmf/trunk/framework/MediaFrameworkIntegrationTest/.actionScriptProperties
osmf/trunk/framework/MediaFrameworkIntegrationTest/org/osmf/MediaFrameworkIntegrationTest s.as
osmf/trunk/framework/MediaFrameworkIntegrationTest/org/osmf/net/TestNetContentProtectable .as
Added Paths:
osmf/trunk/framework/MediaFrameworkIntegrationTest/org/osmf/video/
osmf/trunk/framework/MediaFrameworkIntegrationTest/org/osmf/video/TestVideoElement.as
Property Changed:
osmf/trunk/framework/MediaFrameworkFlexTest/
osmf/trunk/framework/MediaFrameworkIntegrationTest/Hello Alex,
I don't have an answer for you.
But, can you try to use http://drmtest2.adobe.com:8080/Content/anonymous.f4v with locally hosted OSMF player? This content doens't require user/pass info.
I'm wondering that Google TV's flash player doesn't support prompt dialog.
http://drmtest2.adobe.com/AccessPlayer/player.html requires flash player 11. That's why it won't be loaded with flash player 10.x.
Thanks,
-- Hiroshi -
When making a function module, what is difference between test /unit test
best regards,
Hi,
ABAP Unit Tests
Structure of Unit Tests
An ABAP Unit test unit (TU) can be a class, function pool, executable program, or module pool. You can call ABAP Unit for testing individual TUs from the Class Builder (SE24), Function Builder (SE37), ABAP Editor (SE38), and SE80. Mass tests can be carried out from the Code Inspector.
You organize your tests into classes and then into test methods, which are all part of the TU. The system checks small units within the TU, hence the name ABAP Unit. The aim of a test method is to check whether a unit returns the desired result. For this purpose, there are methods of the service class CL_AUNIT_ASSERT that execute comparisons between target and actual values calculated by a unit. The results of all unit tests of a TU are then shown in the ABAP Unit result display.
Example
Let us look at an example to help clarify this. Our minimalist TU is a percentage calculator that delegates this task to a subroutine:
REPORT Percentages.
PARAMETERS: price TYPE p.
PERFORM minus_ten_percent CHANGING price.
WRITE price.
FORM minus_ten_percent CHANGING fprice TYPE p.
price = fprice * '0.9'.
ENDFORM. "Minus_ten_percent
We add a test class to the report, which tests whether the subroutine correctly calculates the percentage for a specific value.
CLASS test DEFINITION FOR TESTING. "#AU Risk_Level Harmless
"#AU Duration Short
PRIVATE SECTION.
METHODS test_minus_ten_percent FOR TESTING.
ENDCLASS.
CLASS test IMPLEMENTATION.
METHOD test_minus_ten_percent.
DATA: testprice type p value 200.
PERFORM minus_ten_percent CHANGING testprice.
cl_aunit_assert=>assert_equals( act = testprice exp = 180
msg = 'ninety percent not calculated correctly').
ENDMETHOD.
ENDCLASS.
The test class and the test method TEST_MINUS_TEN_PERCENT are recognized by the tool through the addition FOR TESTING. The additions "#AU RISK_LEVEL HARMLESS and "#AU DURATION SHORT are not optional comments but annotations containing required technical information. With RISK_LEVEL you specify to what extent, if at all, executing the test endangers critical data. The time is specified so that any tests in endless loops are automatically cancelled due to a timeout.
In the transaction SAUNIT_CLIENT_SETUP, you can make settings for an entire system with regard to the RISKLEVEL of tests and the times assigned to the individual attributes that specify the permitted duration (DURATION: SHORT, MEDIUM, and LONG). For example, in some development systems you will want to prohibit tests that change important data. If the test is cancelled for any reason, it is possible that some data may be left with invalid values or in an inconsistent state. Therefore, you will set the permitted RISKLEVEL suitably low in such systems.
Service of the Class CL_AUNIT_ASSERT
As parameters, the service method CL_AUNIT_ASSERT=>ASSERT_EQUALS requires a target value and an actual value, which is the result of the tested calculation; it then compares the two values. The MESSAGE parameter should contain a text that explains what went wrong during the test. You can also pass a parameter with the service method CL_AUNIT_ASSERT=>ASSERT_EQUALS that specifies the severity of the error, as well as a parameter stating how to proceed if the test fails: Should the test method simply continue, or should the current test method, the entire test class, or all tests of the TU be canceled?
In addition to this method, the class CL_AUNIT_ASSERT also provides other methods, which execute different checks and pass the results to the framework. Most importantly, you should note that you can use the parameters of the methods of the service class CL_AUNIT_ASSERT to control the flow of the whole unit test and include information in the test methods that will later provide you with important details about any errors in the result display.
ABAP Unit Result Display
On the left side of the result display, all the tests of your TU are grouped into a task. In our case, this is only one test class with a single method:
Via the name of the method, you can see what parts of the test method caused errors during the test:
The message you passed with the service method is displayed at the top. Below that, you can which values diverge and can navigate to the class via the stack line.
In our example, a closer examination of the code reveals that the input parameter of the report was confused with the change parameter of the subroutine. -
[svn:osmf:] 14108: Unit test for F4M Subclip support.
Revision: 14108
Revision: 14108
Author: [email protected]
Date: 2010-02-10 11:37:06 -0800 (Wed, 10 Feb 2010)
Log Message:
Unit test for F4M Subclip support.
Modified Paths:
osmf/trunk/framework/OSMFTest/org/osmf/elements/f4mClasses/TestManifestParser.asHello Alex,
I don't have an answer for you.
But, can you try to use http://drmtest2.adobe.com:8080/Content/anonymous.f4v with locally hosted OSMF player? This content doens't require user/pass info.
I'm wondering that Google TV's flash player doesn't support prompt dialog.
http://drmtest2.adobe.com/AccessPlayer/player.html requires flash player 11. That's why it won't be loaded with flash player 10.x.
Thanks,
-- Hiroshi -
JavaServer Faces Unit Test Framework
Based on my knowledge, there isn't any handy JSF Unit test tools. To facilitate UI developers and QAs to do test, I have created a prototype project to evaluate a solution.
For a Simple JSF enabled JSP file:
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="1.2" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:jsp="http://java.sun.com/JSP/Page">
<jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" />
<f:view>
<h:form>
<h:outputText value="Please input:"/>
<h:inputText id="input1"/>
<br/>
<h:outputText value="Please input a integer:"/>
<h:inputText style="width:50px;" converter="javax.faces.Integer"/>
<h:commandButton value="Submit"/>
</h:form>
</f:view>
</jsp:root>writing a HttpUnit to this page is obviously difficult:
1) Hard to pin-point the html element rendered by input1, because up-level NamingContainer h:form is missing id.
2) More difficult to find the second InputText, because missing two ids.
3) How to assert if the converter really works or not, we can't assert any object in PageBean by HttpUnit.
4) Much more difficult to find those html element if there are several level NamingContainer, such as the component nested within "for-loop".
I perfer not to write HttpUnit and seperate JUnit to PageBean, so if the follow JSP can be used in both test and production environment, work will be much easier:
* test1.jsp
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="1.2" xmlns:test="http://www.yourcompany.com/jsf/test" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:jsp="http://java.sun.com/JSP/Page">
<jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" />
<f:view>
<test:parameter name="abc" value="def"/><!-- setting request parameter -->
<h:form>
<h:outputText value="Please input:"/>
<h:inputText>
<test:set value="hello"
/> <!-- emulate inputing "hello" to the text box -->
<test:assert phase="afterUpdateModelValues" description="InputText1" var="input1" value="#{input1=='hello'}"/><!-- you can try other JSF phases as well, here var "input1" is parent jsf component -->
<test:assert description="InputText1" var="input1" value="#{input1=='hello'}"/>
<!-- use default phase "afterRenderResponse", here var "input1" is HtmlElement fetched from rendered page by HttpUnit -->
</h:inputText>
<br/>
<h:inputText style="width:50px;" converter="javax.faces.Integer">
<test:set actions="all" value="123"/>
<test:assert phase="afterUpdateModelValues" description="Input2 Class Name" var="input2CN" value="#{input2CN.class.name == 'java.lang.Integer'}"/>
<test:assert description="InputText2 value in afterRenderResponse phase" var="input2" value="#{input2=='123'}"/>
<test:assert description="InputText2 Style" var="input2Style" valueAttribute="style" value="#{input2Style=='width:20px;height:25px;'}"/>
</h:inputText>
<br/>
<h:commandButton value="Submit">
<test:action description="Test Sumbit"/><!-- support multi actions -->
</h:commandButton>
</h:form>
</f:view>
</jsp:root> For production jsp you can use normal url, http://server:port/yourapp/faces/test1.jsp, those test:xxx components won't do anything.
For testing a single page, http://server:port/yourapp/faces/TestAction?view=/test1.jsp
For testing more pages, http://server:port/yourapp/faces/TestAction?suite=/suite1.xml and write file:
* suite1.xml
<?xml version='1.0' encoding='UTF-8'?>
<TestSuite>
<page>/test1.jsp</page>
<page>/test2.jsp</page>
</TestSuite> After running this test suite in sun jsf1.0 runtime, the result comes:
<?xml version="1.0" encoding="UTF-8" ?>
<Test suite="/suite1.xml">
<Page id="/test1.jsp">
<Action id="_id13" time="0 hour(s) 0 minute(s) 0 second(s) 31 millisecond(s)" description="Test Sumbit">
<Assert id="_id5" description="InputText1">
<afterUpdateModelValues pass="true" />
</Assert>
<Assert id="_id9" description="Input2 Class Name">
<afterUpdateModelValues pass="true" />
</Assert>
<Assert id="_id6" description="InputText1">
<afterRenderResponse pass="true" />
</Assert>
<Assert id="_id10" description="InputText2 value in afterRenderResponse phase">
<afterRenderResponse pass="true" />
</Assert>
<Assert id="_id11" description="InputText2 Style">
<afterRenderResponse pass="false" />
</Assert>
</Action>
</Page>
<Page id="/test2.jsp">
</Page>
</Test> So far, if you think this idea is good for you, you can get the src code at the end of this post.
Furthermore, you can make improvement to this as well, such as implement concurrent and repeatable test.
Anyway, don't expect this two days prototype is quite robust, and coding is not my day to day work either.
If you have any questions or idea, please drop me a line: [email protected], [email protected]
* jsftest.tld
<?xml version="1.0"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>test</short-name>
<uri>http://www.yourcompany.com/jsf/test</uri>
<display-name>JSF Test Tag Library</display-name>
<description></description>
<tag>
<name>action</name>
<tag-class>com.yourcompany.jsf.ui.test.taglib.ActionTag</tag-class>
<body-content>empty</body-content>
<display-name>Action</display-name>
<description>JSF test submit action</description>
<attribute>
<name>binding</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>description</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>assert</name>
<tag-class>com.yourcompany.jsf.ui.test.taglib.AssertTag</tag-class>
<body-content>empty</body-content>
<display-name>Assert</display-name>
<description>JSF test assertion</description>
<attribute>
<name>binding</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>actions</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>default value is "all", means all actions, use "," as delimeter</description>
</attribute>
<attribute>
<name>phase</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>effective value can be anyone of: afterRestoreView,
beforeApplyRequestValues, afterApplyRequestValues,
beforeProcessValidations, afterProcessValidations,
beforeUpdateModelValues, afterUpdateModelValues,
beforeInvokeApplication, afterInvokeApplication,
beforeRenderResponse, afterRenderResponse
The default value is afterRenderResponse, this assertion will be applied to HtmlElement rather than JSF Component.
</description>
</attribute>
<attribute>
<name>value</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>must be boolean, means pass test or not</description>
</attribute>
<attribute>
<name>var</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>variable name, used to define a request attribute which can be used in valueBinding language</description>
</attribute>
<attribute>
<name>valueAttribute</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>The default is "value".
var will be bound to this attribute.
var will be bound to the rendered HtmlElement if the phase="afterRenderResponse",
otherwise var will be bound to parent component.
</description>
</attribute>
<attribute>
<name>postback</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>The default is "true".
Currently only support true;
</description>
</attribute>
<attribute>
<name>description</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>parameter</name>
<tag-class>com.yourcompany.jsf.ui.test.taglib.ParameterTag</tag-class>
<body-content>empty</body-content>
<display-name>Set</display-name>
<description>JSF test request parameter setter</description>
<attribute>
<name>binding</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>actions</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>default value is "all", means all actions, use "," as delimeter</description>
</attribute>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>set</name>
<tag-class>com.yourcompany.jsf.ui.test.taglib.SetTag</tag-class>
<body-content>empty</body-content>
<display-name>Set</display-name>
<description>JSF test component value setter</description>
<attribute>
<name>binding</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>actions</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<description>default value is "all", means all actions, use "," as delimeter</description>
</attribute>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
* faces-config.xml
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<component>
<component-type>com.yourcompany.jsf.ui.test.Action</component-type>
<component-class>com.yourcompany.jsf.ui.test.component.Action</component-class>
</component>
<component>
<component-type>com.yourcompany.jsf.ui.test.Assert</component-type>
<component-class>com.yourcompany.jsf.ui.test.component.Assert</component-class>
</component>
<component>
<component-type>com.yourcompany.jsf.ui.test.Parameter</component-type>
<component-class>com.yourcompany.jsf.ui.test.component.Parameter</component-class>
</component>
<component>
<component-type>com.yourcompany.jsf.ui.test.Set</component-type>
<component-class>com.yourcompany.jsf.ui.test.component.Set</component-class>
</component>
<lifecycle>
<phase-listener>com.yourcompany.jsf.ui.test.listener.TestPhaseListener</phase-listener>
<phase-listener>com.yourcompany.jsf.ui.test.listener.TestAssertPhaseListener</phase-listener>
</lifecycle>
</faces-config>
* TestPhaseListener.java
package com.yourcompany.jsf.ui.test.listener;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import com.meterware.httpunit.HTMLElement;
import com.meterware.httpunit.PostMethodWebRequest;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.sun.faces.renderkit.html_basic.HtmlResponseWriter;
import com.yourcompany.jsf.ui.component.UIIterate;
import com.yourcompany.jsf.ui.test.component.Action;
import com.yourcompany.jsf.ui.test.component.Assert;
import com.yourcompany.jsf.ui.test.component.Parameter;
import com.yourcompany.jsf.ui.test.component.Set;
import com.yourcompany.jsf.ui.test.report.Constants;
import com.yourcompany.jsf.ui.test.report.TestAction;
import com.yourcompany.jsf.ui.test.report.TestAssert;
import com.yourcompany.jsf.ui.test.report.TestPage;
import com.yourcompany.jsf.ui.test.report.TestReport;
import com.yourcompany.jsf.ui.util.ComponentUtil;
public class TestPhaseListener implements PhaseListener {
public TestPhaseListener() {
super();
// TODO Auto-generated constructor stub
/* (non-Javadoc)
* @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
public void afterPhase(PhaseEvent event) {
if(-1 != event.getFacesContext().getViewRoot().getViewId().indexOf("TestAction")){
FacesContext context = event.getFacesContext();
ViewHandler vh = context.getApplication().getViewHandler();
HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
TestReport report = new TestReport();
request.getSession().setAttribute(Constants.TEST_REPORT_SESSION_ATTRIBUTE_ID, report);
String suitefile = request.getParameter("suite");
List pages = new ArrayList(5);
if(suitefile==null){
pages.add(request.getParameter("view"));
}else{
report.setSuiteId(suitefile);
try{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream ins = context.getExternalContext().getResourceAsStream(suitefile);
Document doc = builder.parse(ins);
NodeList pageNodes = doc.getElementsByTagName("page");
for(int i=0; i<pageNodes.getLength(); i++){
pages.add(((Text)pageNodes.item(i).getFirstChild()).getData());
}catch(Exception e){
report.setException(e);
for(Iterator p=pages.iterator(); p.hasNext(); ){
String viewId = (String)p.next();
UIViewRoot view = vh.restoreView(context, viewId);
if(view==null){
try{
WebConversation wc = new WebConversation();
wc.putCookie("JSESSIONID", request.getSession().getId());
String url = getUrl(request, viewId);
WebResponse wr = wc.getResponse(url);
}catch(Exception e){
report.setException(e);
view = vh.restoreView(context, viewId);
try{
Method doActionMethod = TestPhaseListener.class.getDeclaredMethod("doAction", new Class[]{Action.class, FacesContext.class, HttpServletRequest.class, UIViewRoot.class, String.class});
ComponentUtil.iterateComponent(view, Action.class, this, doActionMethod, new Object[]{context, request, view, viewId});
}catch(Exception e){
report.setException(e);
//render report
renderReport(context, report);
request.getSession().removeAttribute(Constants.TEST_REPORT_SESSION_ATTRIBUTE_ID);
context.responseComplete();
/* (non-Javadoc)
* @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
public void beforePhase(PhaseEvent event) {
/* (non-Javadoc)
* @see javax.faces.event.PhaseListener#getPhaseId()
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
private String getUrl(HttpServletRequest request, String viewId){
return request.getScheme()+"://" + request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/faces"+viewId;
protected void doAction(Action action, FacesContext context, HttpServletRequest request, UIViewRoot view, String viewId){
try{
WebConversation wc = new WebConversation();
wc.putCookie("JSESSIONID", request.getSession().getId());
String url = getUrl(request, viewId);
WebRequest wrq = new PostMethodWebRequest(url);
wrq.setParameter(Constants.TEST_VIEW_PARAMETER, viewId);
wrq.setParameter(Constants.TEST_ACTION_PARAMETER, action.getId());
//set parameters
try{
Method doParameterMethod = TestPhaseListener.class.getDeclaredMethod("doParameter", new Class[]{Parameter.class, String.class, WebRequest.class});
ComponentUtil.iterateComponent(view, Parameter.class, this, doParameterMethod, new Object[]{action.getId(), wrq});
}catch(Exception e){
e.printStackTrace();
//set attributes
//set values
try{
Method doSetMethod = TestPhaseListener.class.getDeclaredMethod("doSet", new Class[]{Set.class, FacesContext.class, String.class, WebRequest.class});
ComponentUtil.iterateComponent(view, Set.class, this, doSetMethod, new Object[]{context, action.getId(), wrq});
}catch(Exception e){
e.printStackTrace();
//do test actions
String formId = null;
if(formId!=null)wrq.removeParameter(formId);
formId = ComponentUtil.getForm(action).getClientId(context);
wrq.setParameter(formId, action.getParent().getClientId(context));
long start = System.currentTimeMillis();
WebResponse wrp = wc.getResponse(wrq);
//System.out.println(wrp.getText());
//do assertions
try{
Method doAssertMethod = TestPhaseListener.class.getDeclaredMethod("doAssert", new Class[]{Assert.class, FacesContext.class, HttpServletRequest.class, String.class, String.class, String.class, WebResponse.class});
ComponentUtil.iterateComponent(view, Assert.class, this, doAssertMethod, new Object[]{context, request, viewId, action.getId(), action.getDescription(), wrp});
}catch(Exception e){
e.printStackTrace();
TestReport report = (TestReport)request.getSession().getAttribute(Constants.TEST_REPORT_SESSION_ATTRIBUTE_ID);
report.getPage(viewId).getAction(action.getId()).setTime(System.currentTimeMillis()-start);
}catch(Exception e){
e.printStackTrace();
protected void doParameter(Parameter parameter, String actionId, WebRequest wrq){
if("all".equals(parameter.getActions()) || Arrays.asList(parameter.getActions().split(",")).contains(actionId))wrq.setParameter(parameter.getName(), parameter.getValue());
protected void doSet(Set set, FacesContext context, String actionId, WebRequest wrq){
if("all".equals(set.getActions()) || Arrays.asList(set.getActions().split(",")).contains(actionId))wrq.setParameter(set.getParent().getClientId(context), set.getValue());
protected void doAssert(Assert ast, FacesContext context, HttpServletRequest request, String viewId, String actionId, String actionDescription, WebResponse wrp){
if(("all".equals(ast.getActions()) || Arrays.asList(ast.getActions().split(",")).contains(actionId)) && "afterRenderResponse".equals(ast.getPhase())){
TestReport report = (TestReport)request.getSession().getAttribute(Constants.TEST_REPORT_SESSION_ATTRIBUTE_ID);
try{
HTMLElement targetElement = wrp.getElementWithID(ast.getParent().getClientId(context));
if(targetElement==null)targetElement = wrp.getElementsWithName(ast.getParent().getClientId(context))[0];
if(targetElement==null)request.setAttribute(ast.getVar(), null);
else request.setAttribute(ast.getVar(), targetElement.getAttribute(ast.getValueAttribute()));
//report assert
report.report(viewId, actionId, actionDescription, ast.getId(), ast.getDescription(), ast.getPhase(), (Boolean)ast.getValue(), null);
}catch(Exception e){
report.report(viewId, actionId, actionDescription, ast.getId(), ast.getDescription(), ast.getPhase(), Boolean.FALSE, e);
protected void renderReport(FacesContext context, TestReport report){
try{
HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getResponse();
response.setContentType("text/xml; charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
ResponseWriter writer = new HtmlResponseWriter(response.getWriter(), null, null);
context.setResponseWriter(writer);
writer.startDocument();
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
writer.startElement("Test", null);
if(report.getSuiteId()!=null)writer.writeAttribute("suite", report.getSuiteId(), null);
for(Iterator p=report.listPages().iterator(); p.hasNext(); ){
TestPage page = (TestPage)p.next();
writer.startElement("Page", null);
writer.writeAttribute("id", page.getViewId(), null);
for(Iterator i=page.listActions().iterator(); i.hasNext(); ){
TestAction action = (TestAction)i.next();
writer.startElement("Action", null);
writer.writeAttribute("id", action.getId(), null);
writer.writeAttribute("time", getElapsedTime(action.getTime()), null);
if(action.getDescription()!=null)writer.writeAttribute("description", action.getDescription(), null);
for(Iterator j=action.getAsserts().values().iterator(); j.hasNext(); ){
TestAssert ast = (TestAssert)j.next();
writer.startElement("Assert", null);
writer.writeAttribute("id", ast.getId(), null);
if(ast.getDescription()!=null)writer.writeAttribute("description", ast.getDescription(), null);
for(Iterator k=ast.getStatus().keySet().iterator(); k.hasNext(); ){
String phase = (String)k.next();
writer.startElement(phase, null);
writer.writeAttribute("pass", ast.getStatus().get(phase).toString(), null);
writer.endElement(phase);
if(ast.getException()!=null){
writer.startElement("Exception", null);
StackTraceElement[] stack = ast.getException().getStackTrace();
for(int m=0; m<stack.length; m++){
writer.write(stack[m].toString());
writer.write("\r\n");
writer.endElement("Exception");
writer.endElement("Assert");
if(action.getException()!=null){
writer.startElement("Exception", null);
StackTraceElement[] stack = action.getException().getStackTrace();
for(int m=0; m<stack.length; m++){
writer.write(stack[m].toString());
writer.write("\r\n");
writer.endElement("Exception");
writer.endElement("Action");
if(page.getException()!=null){
writer.startElement("Exception", null);
StackTraceElement[] stack = page.getException().getStackTrace();
for(int m=0; m<stack.length; m++){
writer.write(stack[m].toString());
writer.write("\r\n");
writer.endElement("Exception");
writer.endElement("Page");
if(report.getException()!=null){
writer.startElement("Exception", null);
StackTraceElement[] stack = report.getException().getStackTrace();
for(int m=0; m<stack.length; m++){
writer.write(stack[m].toString());
writer.write("\r\n");
writer.endElement("Exception");
writer.endElement("Test");
writer.endDocument();
response.getWriter().flush();
response.getWriter().close();
}catch(Exception e){
e.printStackTrace();
public static String getElapsedTime(long millis) {
long hours, minutes, seconds, ms;
hours = millis / 3600000;
millis = millis - (hours * 3600000);
minutes = millis / 60000;
millis = millis - (minutes * 60000);
seconds = millis / 1000;
ms = millis - (seconds * 1000);
return hours
+ " hour(s) "
+ minutes
+ " minute(s) "
+ seconds
+ " second(s) "
+ ms
+ " millisecond(s)";
* TestAssertPhaseListener.java
package com.yourcompany.jsf.ui.test.listener;
import java.lang.reflect.Method;
import java.util.Arrays;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.beanutils.PropertyUtils;
import com.yourcompany.jsf.ui.test.component.Assert;
import com.yourcompany.jsf.ui.test.report.Constants;
import com.yourcompany.jsf.ui.test.report.TestReport;
import com.yourcompany.jsf.ui.util.ComponentUtil;
public class TestAssertPhaseListener implements PhaseListener {
public TestAssertPhaseListener() {
super();
// TODO Auto-generated constructor stub
/* (non-Javadoc)
* @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
public void afterPhase(PhaseEvent event) {
if(PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))return;
iterateAssert(event, false);
/* (non-Javadoc)
* @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
public void beforePhase(PhaseEvent event) {
if(PhaseId.RESTORE_VIEW.equals(event.getPhaseId()))return;
iterateAssert(event, true);
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
protected void iterateAssert(PhaseEvent event, boolean before){
FacesContext context = event.getFacesContext();
HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
String viewId = request.getParameter(Constants.TEST_VIEW_PARAMETER);
String actionId = request.getParameter(Constants.TEST_ACTION_PARAMETER);
if(actionId!=null){
TestReport report = (TestReport)request.getSession().getAttribute(Constants.TEST_REPORT_SESSION_ATTRIBUTE_ID);
UIViewRoot view = context.getViewRoot();
if(view==null)return;
try{
Method doAssertMethod = TestAssertPhaseListener.class.getDeclaredMethod("doAssert", new Class[]{Assert.class, FacesContext.class, HttpServletRequest.class, String.class, String.class, String.class});
ComponentUtil.iterateComponent(view, Assert.class, this, doAssertMethod, new Object[]{context, request, viewId, actionId, this.getAssertPhase(event.getPhaseId(), before)});
}catch(Exception e){
report.getPage(viewId).getAction(actionId).setException(e);
protected void doAssert(Assert ast, FacesContext context, HttpServletRequest request, String viewId, String actionId, String assertPhase){
if(("all".equals(ast.getActions()) || Arrays.asList(ast.getActions().split(",")).contains(actionId)) && assertPhase.equals(ast.getPhase())){
TestReport report = (TestReport)request.getSession().getAttribute(Constants.TEST_REPORT_SESSION_ATTRIBUTE_ID);
try{
request.setAttribute(ast.getVar(), PropertyUtils.getProperty(ast.getParent(), ast.getValueAttribute()));
//report assert
report.report(viewId, actionId, null, ast.getId(), ast.getDescription(), ast.getPhase(), (Boolean)ast.getValue(), null);
}catch(Exception e){
report.report(viewId, actionId, null, ast.getId(), ast.getDescription(), ast.getPhase(), Boolean.FALSE, e);
protected String getAssertPhase(PhaseId phaseId, boolean before){
String perfix = before ? "before" : "after";
if(PhaseId.RESTORE_VIEW.equals(phaseId))return perfix+"RestoreView";
if(PhaseId.APPLY_REQUEST_VALUES.equals(phaseId))return perfix+"ApplyRequestValues";
if(PhaseId.PROCESS_VALIDATIONS.equals(phaseId))return perfix+"ProcessValidations";
if(PhaseId.UPDATE_MODEL_VALUES.equals(phaseId))return perfix+"UpdateModelValues";
if(PhaseId.INVOKE_APPLICATION.equals(phaseId))return perfix+"InvokeApplication";
if(before && PhaseId.RENDER_RESPONSE.equals(phaseId))return "beforeRenderResponse";
return "";
* UIIterate.java
// This class brings "To Neoreborn:
If I understand right, Shale only provides some mock core JSF objects and extends JUnit so that you can do junit test to your java classes.
What I concern is to test Pages(JSP) rather than java classes. I want to assert component attribute values within all lifecycle including rendered HTML script. Currently, there isn't any good tools to do this kind of JSP Unit test, am I right? -
While unit testing complex formating, I hit several problems. Below are simple tests that fail with an error. Does anybody know what is wrong with these tests?
Thanks for any hints,
Marc
public function test_apply_Link():void
var init:XML = <TextFlow xmlns="http://ns.adobe.com/textLayout/2008"><p><span>aaa</span></p></TextFlow>
var textFlow:TextFlow = TextConverter.importToFlow(init, TextConverter.TEXT_LAYOUT_FORMAT)
var editManager:IEditManager = new EditManager()
textFlow.interactionManager = editManager
editManager.selectRange(1,2)
editManager.applyLink("http://livedocs.adobe.com/", "_self", true) // throws error:
RangeError: Error #2006: The supplied index is out of bounds.
at flash.text.engine::GroupElement/replaceElements()
at flashx.textLayout.elements::ParagraphElement/http://ns.adobe.com/textLayout/internal/2008::insertBlockElement()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_core\src\flashx\textLayout\elements\ParagraphElement.as:277]
at flashx.textLayout.elements::FlowLeafElement/http://ns.adobe.com/textLayout/internal/2008::createContentElement()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_core\src\flashx\textLayout\elements\FlowLeafElement.as:95]
at flashx.textLayout.elements::SpanElement/http://ns.adobe.com/textLayout/internal/2008::createContentElement()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_core\src\flashx\textLayout\elements\SpanElement.as:77]
at flashx.textLayout.elements::ParagraphElement/http://ns.adobe.com/textLayout/internal/2008::createTextBlock()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_core\src\flashx\textLayout\elements\ParagraphElement.as:100]
at flashx.textLayout.elements::ParagraphElement/http://ns.adobe.com/textLayout/internal/2008::createContentElement()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_core\src\flashx\textLayout\elements\ParagraphElement.as:241]
at flashx.textLayout.elements::SubParagraphGroupElement/http://ns.adobe.com/textLayout/internal/2008::setParentAndRelativeStart()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_core\src\flashx\textLayout\elements\SubParagraphGroupElement.as:178]
at flashx.textLayout.elements::LinkElement/http://ns.adobe.com/textLayout/internal/2008::setParentAndRelativeStart()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_core\src\flashx\textLayout\elements\LinkElement.as:495]
at flashx.textLayout.elements::FlowGroupElement/replaceChildren()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_core\src\flashx\textLayout\elements\FlowGroupElement.as:764]
at Function/http://adobe.com/AS3/2006/builtin::apply()
at flashx.textLayout.elements::ParagraphElement/replaceChildren()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_core\src\flashx\textLayout\elements\ParagraphElement.as:302]
at flashx.textLayout.edit::TextFlowEdit$/insertNewSPBlock()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_edit\src\flashx\textLayout\edit\TextFlowEdit.as:655]
at flashx.textLayout.edit::TextFlowEdit$/makeLink()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_edit\src\flashx\textLayout\edit\TextFlowEdit.as:503]
at flashx.textLayout.operations::ApplyLinkOperation/doOperation()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_edit\src\flashx\textLayout\operations\ApplyLinkOperation.as:146]
at flashx.textLayout.edit::EditManager/doInternal()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_edit\src\flashx\textLayout\edit\EditManager.as:418]
at flashx.textLayout.edit::EditManager/doOperation()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_edit\src\flashx\textLayout\edit\EditManager.as:321]
at flashx.textLayout.edit::EditManager/applyLink()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_edit\src\flashx\textLayout\edit\EditManager.as:1137]
public function test_undo():void
var init:XML = <TextFlow xmlns="http://ns.adobe.com/textLayout/2008"><p><span>aaa</span></p></TextFlow>
var textFlow:TextFlow = TextConverter.importToFlow(init, TextConverter.TEXT_LAYOUT_FORMAT)
var undoManager:IUndoManager = new UndoManager()
var editManager:IEditManager = new EditManager(undoManager)
textFlow.interactionManager = editManager
editManager.selectRange(1,2)
var format:TextLayoutFormat = new TextLayoutFormat()
format.fontWeight = FontWeight.BOLD
editManager.applyLeafFormat(format)
undoManager.undo() // throws error:
TypeError: Error #1009: Cannot access a property or method of a null object reference
at flashx.textLayout.edit::EditManager/performUndo()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_edit\src\flashx\textLayout\edit\EditManager.as:540]
at flashx.textLayout.operations::FlowOperation/performUndo()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_edit\src\flashx\textLayout\operations\FlowOperation.as:181]
at flashx.undo::UndoManager/undo()[E:\dev\trunk\frameworks\projects\textLayout\textLayout_edit\src\flashx\undo\UndoManager.as:197]For your second issue, you didn't display TextFlow before you selected the Text. I also changed the FontWeight.BOLD to "bold" in order to pass compilation. The code below should work:
var
var controllerOne:ContainerController = new ContainerController(container, 500, 500);
var undoManager:IUndoManager = new UndoManager()
var init:XML = <TextFlow xmlns="http://ns.adobe.com/textLayout/2008"><p><span>aaa</span></p></TextFlow>
var textFlow:TextFlow = TextConverter.importToFlow(init, TextConverter.TEXT_LAYOUT_FORMAT)
addChild(container);
textFlow.flowComposer.addController(controllerOne);
textFlow.flowComposer.updateAllControllers();
var editManager:IEditManager = new EditManager();textFlow.interactionManager = editManager;
editManager.selectRange(1,2)
var format:TextLayoutFormat = new TextLayoutFormat();format.fontWeight ="bold";container:Sprite = new Sprite();
editManager.applyLeafFormat(format);
undoManager.undo();
textFlow.flowComposer.updateAllControllers(); -
Unit testing in J2EE environment
Hi All:
We have been trying to use Junit for creating unit test scripts, and have been bit successful in unit testing DAOs and Value objects - but problem is testing of components like EJBs and Servlets or even classes like Actions or Commands. Since these components run under application server environment, I am not sure how to unit test them without either deploying them on the actual server or simulating app server and rest of the system.
I was wondering if people could share their experience in writing unit test scripts especially for J2EE components - like Servlets, JSPs and EJBs. On the similar note, is there any similar tool or API for creating integration test scripts?
Thanks,Well - we already have couple of other servers but that's for beta, QA and Integration testing. Problem is with the unit testing. In unit testing, some piece of code is tested by itself. And I am not sure how I can unit test some of the classes like Servlets, EJBs, JSPs or even dependent classes like Commands or Actions. For example, consider following Action class from Java Pet Store:
public final class CartHTMLAction extends HTMLActionSupport {
public Event perform(HttpServletRequest request)
throws HTMLActionException {
// Extract attributes we will need
String actionType= (String)request.getParameter("action");
HttpSession session = request.getSession();
// get the shopping cart helper
CartEvent event = null;
if (actionType == null) return null;
if (actionType.equals("purchase")) {
String itemId = request.getParameter("itemId");
event = new CartEvent(CartEvent.ADD_ITEM, itemId);
else if (actionType.equals("remove")) {
String itemId = request.getParameter("itemId");
event = new CartEvent(CartEvent.DELETE_ITEM, itemId);
else if (actionType.equals("update")) {
Map quantities = new HashMap();
Map parameters = request.getParameterMap();
for (Iterator it = parameters.keySet().iterator();
it.hasNext(); ) {
String name = (String) it.next();
String value = ((String[]) parameters.get(name))[0];
final String ITEM_QTY = "itemQuantity_";
if (name.startsWith(ITEM_QTY)) {
String itemID = name.substring(ITEM_QTY.length());
Integer quantity = null;
try {
quantity = new Integer(value);
catch (NumberFormatException nfe) {
quantity = new Integer(0);
quantities.put(itemID, quantity);
event = CartEvent.createUpdateItemEvent(quantities);
return event;
In order to unit test above class from say, JUnit test script class, I will have to pass HttpServletRequest object to its method - I will also have to store corresponding command params and store them in the request object - how will you write unit test script for the above class? -
Unit Testing of servlets and jsp by Junit
hi,
suggest me how to do the unit testing by junit!
thanks in advanceOr abstract the business logic away from the actual servlets themselves (always a good idea) and test those classes outside the context of a servlet framework.
That limits the code that actually is impacted by being a servlet to the absolute minimum (essentially parameter passing). -
Unit Testing and APEX Global Variables
We've recently started to unit test our database level PL/SQL business logic.
As such we have a need to be able to simulate or provide output from PL/SQL APEX components in order to facilitate testing of these components.
Some of the most obvious portions that need simulation are:
1. The existence of a session
2. The current application ID
3. The current page ID.
We currently handle requirement #1 by using apex_040100.wwv_flow_session.create_new
We handle 2 and 3 using the apex_application.g_flow_id and g_flow_step_id global variables.
I'm just wondering, how safe is it for us to use wwv_flow_session.create_new to simulate the creation of a session at testing time for those things which need a session?
I've also noticed that there are apex_application.get_application_id and apex_application.get_page_id functions whose output is not tied to the global variables (at least in our current version).
Is it safe for us to expect that we can set these global variables for use in testing or is apex moving to get_application_id and get_page_id functions away from global variables?
Will there be corresponding set_application_id and set_page_id functions in the future?
Sorry for the question bomb. Thanks for any help.My first question would be why do you need to establish a session to test your PL/SQL?
wwv_flow_session is a package internal to APEX, and you should probably leave it be.
The get_application_id procedure you refer to is in apex_application_install, which is used for scripting installation of applications - not get/set of page ID like you're describing.
If you're uncomfortable using apex_application.g_flow_id, you can use v('APP_ID') or preferably pass the app_id/page_id as parameters to your procedures.
Your question seems to have a few unknowns, so that's the best I can describe.
Scott -
Suggestions requested for Unit Testing process and build processes.
Hi All,
We are using WebLogic WorkShop 8.1 SP2 to build our WebApp. One thing I am trying
to get together is a "Best Practises" list for aspects of WorkShop developement,
particularly Unit Testing, Continous Build methodology, source control management
etc.I have been through the "Best Practises Guide" that comes in WorkShop help,
but it doesnt address these issues.This could help us all for future projects.
1)Could anyone give pointers on how to perform Unit Testing using either JUnit/JUnitEE
in the WorkShop realm, given that Controls cannot be accessed directly from PO
Test classes.
2)For a project of size say 5 developers ,does it make sense to have a nightly
build using tools like CruiseControl?We use CVS for our source control and its
working out pretty well, but given that we currently have no Unit Tests that can
be run after the build and that can provide some reports on what broke/what didnt?
I am sure we all would appreciate any suggestions and more questions on this topic.
Thanks,
Vik.Hi, Chris,
can you perhaps explain your solution in greater detail. I am really curious to
find a way to test controls.
"Chris Pyrke" <[email protected]> wrote:
>
I have written (well it's a bit of a dirty hack really) something that
lends itself
to the name ControlTest (it unit tests controls). Its a blend of Junit
and Cactus
with some of the source of each brutalised a bit to get things to work
(not much
- it was a couple of hours work, when I was supposed to be doing something
else).
To write a control test you code something like...
package com.liffe;
import com.liffe.controlunit.ControlTestCase;
import controls.Example;
public class TestExample extends ControlTestCase
private Example example = null;
public void setUp() {
example = (Example)getControl("example");
public void testExample() {
this.assertNotNull(example);
String result = example.getData();
assertEquals(result, "Happy as Larry");
Other tasks required to set up a test are creating a web project with
a jpf which
needs some cut and paste code (14 lines) in its begin method and a jsp
which is
also cut and paste (5 lines). (ie create a standard web project and paste
in 2
pieces of code)
In the web project you need to create a control (A) with an instance
name of controlContainer.
(if it's called something else the pasted in code will need changing
to reflect)
In this control you need to put an instance of TestContainerImpl and
any controls
that need testing.
You then need to add a method to the control (A) that looks like…
* @common:operation
public String controlTestRun(String theSuiteClassName, boolean xsl)
container.setControl("example", example);
return container.controlTestRun(theSuiteClassName, xsl);
You need to call container.setControl for each control being tested and
the object
'container' is the instance name of the TestContainerImpl that was put
in.
There are 4 jars (junit, cactus etc) that go in the library. You will
also need
the ControlUnitBase project (or maybe just it's jar).
To use you call a URL like:
http://localhost:7001/TestWeb/Controller.jpf?test=com.liffe.TestExample
TestWeb is the name I gave to my web project - this will be different
for each
test project
com.liffe.Example is the class above and will therefore be different
for each
test case.
You can also call
http://localhost:7001/TestWeb/Controller.jpf?test=com.liffe.TestExample&xsl=true
(Note the extra &xsl=true) and the browser will (if it can) render it
more prettily.
This seems to do the job quite nicely, but there are several caveats
I would hope
someone from bea would be able to address before I start using it widely.
1) To access the control you need to create it (eg as a subcontrol in
the control
(A) above.
To get it into the test case you need to pass it round as an Object (can't
return
Control from a control operation). As it's being passed around among
Java (POJO)
classes I'm assuming that control remains in the control container context
so
this is OK. It seems to work and the Object is some form of proxy as
any control
seems to be reproxied before the control is invoked from the test case.
2) If I'm testing controls called from a JPD then they either need to
be in a
control project (and my test cases called from a Web Project) which makes
for
a large increase in project numbers (we already have this and are trying
to resist
it) To avoid this - as a process project is a brain damaged web project
I simply
perform some brain surgery and augment the process project with some
standard
files found in any old web project. this means I can call the test JPF
from a
browser. This seems nasty, is there a better way?
3) I would like to be able to deliver without the test code. At the worst
the
code can be in place but must be inacessible in a production environment.
I don't
know how best to do this - any suggestions (without creating lots of
projects,
or lots of manual effort)
If anyone has read this far I would ask the question does this seem like
the kind
of thing that would be useful?
Hopefully a future version of workshop will have something to enable
unit testing
and this hacking will be unnecessary.
Could someone from BEA tell me if this is a dangerous way to do things?
Chris
"vik" <[email protected]> wrote:
Hi All,
We are using WebLogic WorkShop 8.1 SP2 to build our WebApp. One thing
I am trying
to get together is a "Best Practises" list for aspects of WorkShop developement,
particularly Unit Testing, Continous Build methodology, source control
management
etc.I have been through the "Best Practises Guide" that comes in WorkShop
help,
but it doesnt address these issues.This could help us all for future
projects.
1)Could anyone give pointers on how to perform Unit Testing using either
JUnit/JUnitEE
in the WorkShop realm, given that Controls cannot be accessed directly
from PO
Test classes.
2)For a project of size say 5 developers ,does it make sense to have
a nightly
build using tools like CruiseControl?We use CVS for our source control
and its
working out pretty well, but given that we currently have no Unit Tests
that can
be run after the build and that can provide some reports on what broke/what
didnt?
I am sure we all would appreciate any suggestions and more questions
on this topic.
Thanks,
Vik.
Maybe you are looking for
-
Multiple Apple Remotes no longer work with Apple TV!
I've been using Apple TVs since the minute Steve Jobs introduced them in 2007. I bought the 2nd and 3rd Generation Apple TVs the minute each of them were introduced. I've been watching every Apple Keynote Address since they were available online or o
-
Having trouble setting up calendar...
So I just set up iCloud....I have a MacBook Pro, an iPhone 4 and an iPad 2. I want the calendar from my computer to be synced with my other devices - so in the settings of iCloud on my computer I have Calendars selected to merge. But, the calendar is
-
Can I "reset" hard drive capacity
I'm not sure how it happened (although I suspect it was during an aborted install of Bootcamp), but an 80GB external (firewire) hard drive now shows up as a 55GB hard drive. I have tried everything I can think of -- well, OK, Disk Utility -- but I ju
-
Iphone 4 sending messages from my email not phone number
Yesterday when texting some of my friends they did not know who I was , I then found out my email address was showing up not my phone number. What is going on with this? My phone is up to date and this seems to only happen when I message people with
-
ITunes 9 not syncing podcasts in playlists
My podcasts all sync just fine (they become available in my Podcasts folder), but for some reason PLAYLISTS of podcasts created in iTunes don't sync with my iPod. If I put a SONG in the playlist created in iTunes, it syncs with the iPod, only the pod