When you have made some progress developing modules and components using IBM WebSphere Integration Developer, you'll probably want to test what you have completed. The integration test client makes it easy for you to test your applications, but you might not have had time to explore its full capabilities. Here's some light reading for you. You might just find, over lunch, that the integration test client has a feature or two that will save you time.
Here's a short list of the things that you'll discover:
- Testing modules: selecting one or more components in a module to test and testing multiple modules.
- How to reuse common values.
- Attaching to a module when an external client calls components.
- Emulating broken or missing parts of an assembly diagram.
- Saving and rerunning tests.
Also, Table 1 lists some common mistakes associated with the integrated test client, along with the sections that will show you how to correct or avoid them.
Table 1. Common mistakes covered in this article
|Common mistake||Covered in section|
Testing one component when you intend to test the entire module
Retyping common values
Not using the re-run feature
Expecting the integration test client to use a particular import or export binding
Not using the integration test client when testing with other clients
Expecting values to be unset because you did not enter values
If you haven't used the integration test client yet, then here's a quick look at how you test with it. Figure 1 shows integration test client after you right-click a module in the Business Integration view and select Test => Module. To test the module, you select an operation of a component, enter input values, and then click Continue.
Figure 1. Sample figure containing an image
After the test runs, the output of the operation will display as a Return event. Before the operation completes, the data that is passed between components will display in the request and response monitor events (shown in the left side of the editor). The integration test client will pause while a component is being emulated and wait for you to enter the values that you want the emulated operation to return. Figure 2 shows an integration test client run where an emulation event is selected and where the tester entered a return value of true for the checkPurchaseOrder operation.
Figure 2. Running a test
A module often will have one component that calls other components or imports. Typically, a user right-clicks the calling component and selects Test Component, expecting the component that was selected, and each component or import that it calls, to be tested. However, the integration test client takes the test component command literally and tests only the component that was selected; the Test Component menu item really means "test in isolation." The other components, imports, and exports are emulated, which means that you need to enter values that you want the components, imports, and exports to return. Not to worry though, there are a few things that you can do if you don't want to test just one component:
- Use the Test Module menu item.
- Select all of the components, imports, and exports at the same time that you want to test.
- Delete unwanted emulators from the integration test client configuration.
Each of these points is covered in the following sections.
Testing a module
If you want to test all of the components of your module, then you can right-click the assembly editor canvas and select Test Module. The integration test client will automatically emulate anything that can't be called, such as components that have no implementation, imports that have no binding, and references that aren't wired. (We'll talk more about creating emulators in the Emulation section.) If there are other components, references, or imports that you don't want to include in the test, there are things that you can do. For example, if your module has an import with an Enterprise Information System (EIS) binding and you don't presently have access to the EIS, then you can create an emulator for the import. Just switch to the Configuration tab of the integration test client, right-click Emulators, and select Add. Figure 3 shows you how to create an emulator in the Configuration tab of the integration test client.
Figure 3. Creating an emulator
Testing multiple components
If you want to test only some components, rather then selecting Test Module and creating many emulators, you can just select all the components that you don't want emulated. When you right-click a selected component, you'll see a Test Components menu item (Figure 4). A component that wasn't selected will be emulated. If you select a component that can't be called, it will automatically be emulated.
Figure 4. Selecting multiple components for testing
If you're not happy with the emulators that were created based on your selection, (let's say you realize that you accidentally selected a wrong component) then you can switch to the integration test client configuration tab and then add or delete emulators. Remember, if you delete an emulator for a component that isn't implemented or an import that has no binding, you'll get an error when you run the test. If that happens, you can always add back the emulator and re-run your test.
Testing multiple modules
When a module that you are testing calls another module, you should select both modules to be part of the test. The reason is that when you select just one module to test, the integration test client will ensure that only the selected component is deployed before the test starts and will only monitor and emulate components within that module. If that module makes calls to other modules, then you need to remember to deploy the other modules to the server if they are not already deployed and there will be no monitoring or emulations.
To ensure that each selected module is deployed before starting the test, select multiple modules in the Business Integration view, right-click and select Test Module. If the calls between components are made using SCA bindings on the imports and exports, then each other module that was selected will be monitored and emulated. To add or remove modules from your test configuration, you can also use the Configuration tab . When you right-click a configuration and select Add => Module, the New Test Module dialog box (Figure 5) opens. All checked modules will be part of the test configuration and all uncheck modules will be removed from the configuration.
Figure 5. Adding or removing modules from a configuration
When the imports and exports use other bindings, such as a Web Service binding, then the integration test client cannot track the call between the import and export because of the loss of session information on the server as calls are made outside a module. In this case, if you need to monitor or emulate components in the other modules, use the attach feature that we describe in the Attaching to a module section. You open a new integration test client for each module and then attach to the module or, when you select multiple modules, click the attach icon in the integration test client that you opened.
The data pool
You might find yourself entering the same values over and over for some tests. If you do, this is a good opportunity to check out the data pool. Right-click a business object or business object attribute and select Add Value to Pool. By saving the values for the selected business object or attribute from test inputs, output, or monitors into a repository, the value can be reused later. To use a saved value, you just right-click any business object or attribute when you are editing values and select Use Value from Pool. In the case of a business object attribute, the saved value from the data pool is copied to the input editor (or output editor for an emulator). In the case of a business object, all of the values of the attributes are copied, including the values for nested business objects. You can copy business object values from the input editor to the data pool, and you can also copy values from integration test client events of tests you have run, such as monitor and response events.
You can edit the data pool by clicking the Data Pool icon , or by clicking Data Pool under the input editor. The difference is that the Data Pool button will filter the results based on the business object type that is currently selected in the editor and icon will have an empty filter. When you select Use Value from Pool or click Data Pool on the input editor, the values in the data pool are filtered based on the business object type that is selected. You can edit the data pool filter to filter for other business object types, or clear the filter to show all of the types in the data pool.
Figure 6. The data pool editor
You can also save values of one type and then use them in the business objects of other types, which is useful when you have similar data in different business objects. All that matters is that the business object attribute names match. For example, if you had one business object named P with attributes x and y, and you saved it to the data pool, then the value of x will be copied if you used its value in another business object named Q with attributes x and z. You can do this with a nested business object as well. This rule applies not only to adding values to the data pool and then using them, but also when you directly copy and paste values between objects. For example, when the integration test client displays output that contains business object A and you copy and paste the values from A to a similar business object, B, as input of the next test, the matching attributes in B will receive the values copied from A.
For another example, Figure 7 shows the contents of one business object, PO, that was copied to another business object, PurchaseOrder. All the attributes match except for the attribute named desc. Because the desc attribute doesn't match the attribute named description, the value is not copied and the value is left unset. All of the other values are copied.
Figure 7. Copying values between different business objects
If you want to share data pool values between workspaces, there is no easy way to do it. Here's a little trick. You can look at your workspace in the file system and navigate to the directory .metadata\.plugins\com.ibm.wbit.comptest.ui. You'll see a file there named testclient.objectpool. If you copy the testclient.objectpool file to the same location in your friend's workspace, then your friend can use your business object values when she selects Use Value from Pool. Don't forget to tell your friend to restart WebSphere Integration Developer to pick up the new values.
Import from an XML file
Let's stay on the theme of reusing data for a bit. You might already have some input data that is in XML format that you want to use for testing. The integration test client lets you import that data into a business object. The XML file doesn't need to match your business object exactly because the integration test client will try to match the names of elements with the names of the business object attributes. If your XML files are saved SOAP messages, then the integration test client can import those files as well.
Remember that there are limitations in the current version of the integration test client regarding the XML schema constructs that are supported. For example, if your XML has a repeating sequence (a sequence has maxOccurs greater than one, as opposed to a sequence that contains elements, each of which has maxOccurs greater than one), the integration test client will not import the data. In this case, import from the XML file, and then manually enter the values for any values that the test client missed.
Figure 8 shows an XML instance that was imported into the PurchaseOrder type shown in Figure 9. The unset values have no corresponding element in the file. The elements in the file that have no corresponding attribute in the business object are ignored.
Figure 8. An XML instance to be used as test input
Figure 9. Values imported as integration test client input
Attaching to a module
There are times when you might want to emulate or monitor components, but the initial call to a module will begin outside of the integration test client. For example, you might want to test a module where a JSP calls the stand-alone references to call a component in a module, or perhaps another application has called your module through an export. Or you might use the Business Process Choreographer Explorer to launch a business process or originating human task in your module. You could add custom code in the components to monitor the data flow through your module, but you might find it easier in these cases to use the attach mode in the integration test client. In attach mode, the integration test client monitors and emulates components and wires as a module runs, but it doesn't first invoke a component; instead, an external source does the invoking.
To attach the integration test client to a module, right-click a module in the business integration view and select Test => Attach, or you can click the Attach icon in an open integration test client. Figure 10 shows a user testing a module named OrderEntry in attach mode. You can also select multiple modules and test all of them in attach mode, or add additional modules to the integration test client configuration as we mentioned in the Testing modules section. When you test multiple modules in attach mode, you see a list of modules that you have selected or added to the configuration next to Continue.
Figure 10. Attaching to a module
Here's a little trick to help you quickly see how attach mode works if you don't have a JSP to call one of your components.
- In the Business Integration view, right-click a module and select Test => Attach.
- Click Continue. You will be prompted to select which server to listen to events on. After that, nothing interesting happens until there is activity in the module.
- Right-click the same module in the Business Integration view and select Test => Test Module. We're going to pretend that a component in your module is being invoked externally. You now have two integration test clients open: one for attaching and one for invoking. The one for invoking is standing in as an external caller to your module.
- Select a component and operation to call, provide some input, and then click Continue.
- When your test has started to run, switch to the integration test client that is running in attach mode. You'll see the same events displaying as those that display in the integration test client where you invoked a component. The only difference is that there is no initial Invoke event.
Figure 11 shows an integration test client that has attached to a module with a component that was called twice. If multiple integration test clients emulate the same component, then the first one that was started will do the emulating.
Figure 11. Attach sessions
Testing imports and exports
The integration test client does not pass data through the bindings. When you test an export, you are really testing the component that the export is wired to. For example, Figure 12 shows that testing MyInterfaceExport is the same as testing Component3.
Figure 12. Testing an export is equivalent to testing a module that it's wired to
Similarly, when you are testing an import, the integration test client ignores the binding. The integration test client calls the import and lets the binding complete the service call
One of the most common things to do with the integration test client, other than monitoring calls between components, is emulation. As we mentioned frequently, you can emulate components that you don't want to be part of a test, which means that the integration test client will provide return values for a service call. There are two things in an assembly diagram that you can emulate: components (including imports and exports) and references. The integration test client will automatically create an emulator in these situations:
- A component is unimplemented
- An import is unbound
- A reference is unwired
When you add an emulator yourself, as you saw in Figure 3, the New Emulator wizard asks you whether you want to emulate a reference or a component. Emulating a reference is useful when you have an unwired reference and there's no component to emulate, or when you have a reference with multiple wires to other components and you don't want to emulate each component. On the integration test client configuration page for each emulator, there are two settings: Manual emulation (the default) and Programmatic emulation (Figure 13).
The next sections describe each.
With manual emulation, the integration test client stops and waits for you to enter output data, and then sends that data to the caller of the component or reference that was emulated. This type of emulation is created by default any time an emulator is created. This is useful if you don't have much data to enter for the return value, or when the return values can't be computed.
With programmatic emulation, the integration test client runs a piece of Java™ code in place of actually calling a component operation. The Java code can be created using Java or a visual snippet. Using programmatic emulation is useful if you are tired of entering values or even picking values from the data pool every time a component is emulated. Programmatic emulation is also handy if you find it difficult to remember which output to enter or select from the data pool for each case, especially when you need to return specific data based on particular input values. You would also use programmatic emulation in this example: suppose you have a module where ComponentA calls ComponentB, which then calls ComponentC. You want to test your module by calling an operation in Component A and letting the calls to the other two components occur. Now let's say that ComponentB is broken, incomplete, or unavailable. If you have a manual emulator for ComponentB, then ComponentC will not be called, because there is no way to invoke another component from a manual emulator.
In this example, to make sure that ComponentC is called when ComponentB is emulated, you create a programmatic emulator for ComponentB and implement it to make a call to ComponentC. You could also create a temporary component to stand in place of ComponentB, and then rewire your module to use the temporary component. However, the fewer changes you make to your module when testing, the better. You might also forget to undo the wiring before you deploy. When you are no longer using the integration test client, the emulators will no longer be used.
Figure 13. A programmatic emulator in the configuration
When you select Programmatic emulation, and then click New, the New Emulation wizard opens that helps you create a programmatic emulator, asking you where you want the emulator files kept (one file for the emulator and another that holds the Java code). You can also browse for existing programmatic emulators and you can change the Java file for any programmatic emulator at any time.
Figure 14 shows the programmatic emulation editor and Figure 15 shows the implementation for the emulation. You define an emulator for each operation of the component that you expect to be called. The return node of the snippet is the operation response. Note that if you select a programmatic emulation for a component, and an operation is called that your emulation does not implement, you will get an error.
Figure 14. A programmatic emulator
Figure 15. Programmatic emulation editor
In the Java code, or in the visual snippet, you are free to implement whatever logic you want including always returning a business object with specific values, computing return values based on particular input, and making additional service or component calls to build up the return values. When the integration test client runs, the snippet or Java code runs without intervention from you. When the integration test client is not running, then components are no longer emulated and their own implementations run without further changes. (If you have been relying on the integration test client to emulate unwired references or unimplemented components during development, don't forget to complete those missing pieces before deploying your module for production.) To see what values the emulation received and then returned, click the Emulate event. Figure 16 shows a programmatic emulation after it has run.
Figure 16. A programmatic emulation after running
Saving and rerunning tests
Sometimes you get lucky and testing the module the first time shows that everything is perfect and you never need to retest your module. But usually you'll find yourself continually fixing or adding functions, followed by more testing. While the integration test client does not yet have full-featured test case support, it does allow you to save and rerun tests. As you add and remove components, or change the sequence of component interactions, your tests might become invalid, but for the most part, you can keep running the same tests repeatedly without additional input, or only with new manual emulation values.
You can also add or remove monitors and emulations in the configuration as necessary and continue running. For example, you might have run a test with a component emulated. Later, when the emulated component is functioning, you can rerun the test after removing the emulator from the configuration.
You can save everything you see in a integration test client instance including input values, events, manual emulation values, and configuration parameters. When you save the integration test client, it will prompt you for a location and test name. Files are saved in a test_name.exetrace file. To open a saved test, click the load icon on the top tool bar, browse to the project that contains your test files, and then select the .exetrace file for the test that you want to rerun. In addition to rerunning the test, you also might want to save a test run to refer to the inputs and outputs at a later time.
Whether you are using an existing integration test client, or you have opened a saved one, to re-run a test, right-click an Invoke event and choose either Rerun or Rerun with auto-emulate. By choosing Rerun, you caninvoke the component operation with the same input values (you will see the input values in the input editor when you click the Invoke event). Manual emulators will pause for you to enter emulation data. By choosing Rerun with auto-emulate, you can run with the same input values and use the same response values for the manual emulators as were used in the previous run.
Testing on remote servers
When you install WebSphere Integration Developer, you can choose to also install WebSphere Process Server. When you install WebSphere Process Server, the integration test client works out of the box; you just right-click a module or component and select to test it. However, you might already have a server installed, or you might choose to test your modules on a remote server to save resources on your development computer. When WebSphere Process Server is not installed, whether local or remote, there is one step you need to take to enable the integration test client, which involves putting the integration test client runtime JARs in place on the server. When these JARs are on the server, the integration test client works the same whether the server is local or remote.
For the integration test client to work on any server, the WebSphere Process Server or Enterprise Service Bus server must appear in the Server view and the integration test client JARs must be on either server when it starts. To get the integration test client JARs on the server, follow the instructions at http://www.ibm.com/support/docview.wss?rs=2308&uid=swg24010662&acss=wid032007. This WebSphere Integration Developer support page has a WebSphere Process Server update that you install using the IBM Update Installer for WebSphere Software.
To add a server to the Servers view, right-click the view and select New => Server and then follow the instructions in the New Server wizard steps. You might have noticed that the integration test client will prompt you to select a server location when you run a test; you can also use that dialog box to bring up the New Server wizard.
If you install the integration test client update on a production server, don't forget to remove it after you're finished testing. You don't want someone who knows the server password to be able to attach and then monitor or emulate components.
Special integration test client values
Empty String ("")
When a value has a string type, the default value is "" (an empty string). As Figure 17 shows, the value for attribute1 is blank. If you have a blank for a string, then an empty string is used as the input value (or was received as the value in the case of output or emulation input), which is equivalent to calling MyBO.set("attribute1",""). Note that complex types (such as MyBO in Figure 17) also show a blank string because only the simple type fields of a business object can have values.
Figure 17. Special integration test client values
When you want a field to be set to null, you set its value to <null> as attribute3 in Figure 17 shows, which is equivalent to calling MyBO.set("attribute2", null) using the Service Data Object (SDO) API. You can type in <null> or you can select it from the list when you click in the value cell.
When you create a business object in your business logic, fields for which you don't call set() using the SDO API (or assign in the business process editor) are unset. If you want a field in the integration test client to be unset, you set the value to <unset>.
There is one caveat regarding <null> and <unset>: the integration test client can only display either <null> or <unset> for a field. In some cases, such as when displaying data that has come back from the server, a field might have a value even though it is unset (SDO assigns a default value for some types when they are unset). So, you might see a value of <null> or 0.0 when the field is unset.
When you want to create a new instance of a business object, you use the <new> value. You need to create a new instance of a business object when only the name but none of the attributes are showing (Figure 18), such as when you have previously unset the attribute or set it to null, when a circular dependency has been reached (for example, business object A contains business object B, which contains business object A), or when the maximum expansion depth has been reached. In the Preferences, there is a setting that limits how deep nested business objects will be expanded (the default is 5
Figure 18. Creating a new business object instance
To the integration test client, an abstract type is a type that has
abstract=true in the business object schema, where the schema definition is an xsd:any, or the type is xsd:anyType. To enter values for an abstract type, you first need to select a concrete type by clicking the Type column. This action opens the Type selection dialog box, which is the same dialog box that you use to select types in the business object and other editors. Figure 19 shows an abstract business object (AbstractBO) before and after you select a concrete type (ExtensionBO). The pattern used in the type column is Current_Type [Base_Abstract_Type].
Figure 19. Sample figure containing an image
Now you know more about the integration test client and its various features, so that you can get even more mileage out of it and avoid the most common mistakes.
- WebSphere Integration Developer integration test client documentation
- Article series: A guided tour of WebSphere Integration Developer
- Article series: Getting connected with WebSphere Business Integration Adapters
- IBM developerWorks WebSphere business integration zone