Friday, February 15, 2013

What TDD won’t tell you and why BDD is equally important?

Most of us think Test Driven Development is a cycle of test, implement and refactor. In reality its the freedom to start working toward your solution before you can map it all out.

It’s the freedom to make changes knowing your tests will alert you if you have violated a previous assumption that you have forgotten.

Since TDD forces you to write test first, it also forces you to think about how you want to use an API, because that is the very first thing you write down. This is a good thing and it leads to more usable APIs.
TDD also forces you to factor out dependencies in order to be able to mock them. Thats the other point where TDD encourages good design.
Now here comes the twist : There is more to software design than just nice to use APIs and good principles.TDD does almost nothing for you in order to find a good solution for your problem. 
TDD won’t tell you following -
  • Can your domain model represent all the cases needed by the business?
  • Which of all the design patterns would help you? Is there any well known algorithm you could use to solve your problem? 
  • Does the problem become trivial once you approach it in a functional way?
  • Is recursion a solution or a dead end?

Ultimately one has to understand the problem and know lots of possible approaches to a problem in order to design software well. There is just no way around it.
Once you have the solution in your mind, once you know the basic data structures and algorithm you going to use, TDD will help you to implement it in a clean, well factored way.
Having said enough about TDD I would like to now shift my focus on BDD (Behavior Driven Development) and its real value.
TDD is more “low level” talking about unit tests and integration tests and how to write code that tests real code while BDD is about specifications and behaviors.
In TDD we talk about Arrange Act Assert while in BDD we have Given When Then
There are clear cut differences between both. BDD is more “high level” dealing with specifications and was intended to be used by domain experts as well as developers
As a matter of fact one should write unit tests as well as specifications – because we need to test both.
TDD is described by a basic red-green-refactor cycle, I have come across this interesting checklist on dzone which is written in the form of questions we should ask ourselves while going through the different phases of the cycle.


Happy Testing :)

Sunday, January 06, 2013

ATG DUST – A JUnit framework for ATG applications



Well we all have been writing the classic JUnit tests from years now but it becomes challenging to write test cases when you dealing with framework like ATG.
So here comes ATG DUST - A framework for writing JUnit tests for applications built on the ATG Dynamo platform.

Its indeed makes our life lot simpler by providing some amazing features. The highlight of this framework is that it allows one to quickly write test classes that depends on Nucleus or ATG Repositories. By using ATG DUST one can drastically cut down on development time. It takes only a few seconds to start up a test with a repository, not like application server which takes good time to start up.

To get started go straight to first test page . This page will walk you through the process of running a basic test which starts Nucleus.

This tutorial walks you through the steps of writing a test which does not need to run in an application server. This is one of the underlying benefits of writing unit tests.
The test does not depend upon starting up an application server so turnaround time is also very quick.

Visit out-of-the-box-component-testing page which gives you a feel of simple test class. Try to open the java source (StartWithModulesTest.java) file attached there to get a fair idea how easy to use ATG DUST.

The best part I liked about ATG DUST is having the ability to load any specific ATG module and write a quick Repository test class. Go to the repository test page for a simple example.
The repository is started up against an in-memory Hypersonic Database.

DUST also support Formhandler test features with the help of utility (ServletTestUtils) class which can create a dummy Dynamo Request/Response pair.

Some of the key classes to look at –
atg.adapter.gsa.GSATest - A basic GSA test which has several utility methods.
atg.test.util.DBUtils  - Utility code for getting a connection to a database. The most common method is getHSQLDBInMemoryDBConnection.
atg.test.util.FileUtil  - A collection of utility methods for dealing with the file system.
atg.nucleus.NucleusTestUtils - This class contains some utility methods to make it faster to write a unit test that needs to resolve components against Nucleus.

Note on ATG version support – ATG DUST was developed using 9.0 but it work on most ATG versions back to 7.2 . I used ATG DUST version 1.2.2

Download ATG DUST

Thursday, October 11, 2012

Oracle ATG Search 9.3 configuration on Local (Windows 7 , 64 bit) machine

Recently installed ATG search 9.3 on local windows machine and configured search environment and index.  It was a good fun as it gave quite some errors to fix before running my first index on local machine.  I would try to give all the main steps and error faced in this process.


Lets first start with prerequisites –
You should have a working/running Store and BCC JBoss instances in your local system. I also assume that you have already installed Search 9.3 in your local ATG home.

Now let’s focus on search configuration. Kindly follow below steps in same sequence.

1) Delete any existing projects and Environments from Search Admin in BCC Admin screen.
2) Goto Store ACC and delete everything from SearchConfigurationRepository under Content. You may leave searchindex and logicalpartition items in it.

3) Set following remoteHost=localhost , remotePort=8860 in below components as per your local store.
C:\ATG\ATG9.1\home\servers\pub\localconfig\atg\commerce\search\refinement\RemoteCatalogRefineConfigAdapter.properties
C:\ATG\ATG9.1\home\servers\pub\localconfig\atg\commerce\search\config\RemoteCatalogRankConfigAdapter.properties
C:\ATG\ATG9.1\home\servers\pub\localconfig\atg\commerce\search\config\RemoteSearchUpdateAdapter.properties

4) Now goto BCC and create a new search project called production under Search Admin
and add content as below
ATG Repository - Local - /atg/commerce/search/ProductCatalogOutputConfig

5) Now goto "Language Customizations(Pre-Index)" under content option of new project(production)
a) Add Synonyms by using option "Select Custom Term Dictionaries"
b) Add languages like english , italian, french, german, japansese,korean using option "core language support"

6) Now add Post-Index Customizations options in the below sequence ONLY
Merchandising Search Config    - Remote - localhost:8860 - /atg/commerce/search/config/CatalogRankConfigAdapter
Refine Config (Facet Set)           - Remote - localhost:8860 - /atg/commerce/search/refinement/CatalogRefineConfigAdapter
Search Update Config (Auxiliary Data)      - Remote - localhost:8860 - /atg/commerce/search/config/SearchUpdateAdapter

7) Check the Environment - You should see one default one just rename it to production
8) Now build the index and see if it works

If you get this below error at BCC server startup then do the following ---
ERROR [IndexDeploymentService] Swap failed for index 35000001; aborting swap and tearing down staging. Swap rollback Policy Description: All physical partitions must have at least one successfully initialized search engine

1) Add this in Store jboss server run.conf file and restart your store server.
JAVA_OPTS="$JAVA_OPTS -Datg.allowRemoveAllItems=true"

2) Now goto below component in your Store server dyn/admin and do a remove-all-items on all items under SearchConfigurationRepository Item Descriptor.
http://localhost:8180/dyn/admin/nucleus//atg/search/routing/repository/SearchConfigurationRepository/

swapcheck
searchEngine
searchMachine
searchEnvironmentHost
searchEnvironment
physicalPartition
searchIndex
logicalPartition
indexingActivitySummary
indexingCommandCount
deploymentHistory

3) Now do the whole setup again in BCC which we did in above steps thru 4 to 9.

Note -- You also need to increase the TransactionTimeout setting in jboss-service.xml under your store server's conf/ folder.
30000

Note -- You also need to increase heap size setting in JBOSS_OPTS variable in Jboss run.bat file

References –

Let me know if you face any issues with Search setup or if you know of any better way to configure search.

Tuesday, September 04, 2012

SQL Error: ORA-01591: lock held by in-doubt distributed transaction

Well last week I came across this ORA-01591 while running alter command against one of the Oracle DB schema. It simply failed by giving following error. 


SQL Error: ORA-01591: lock held by in-doubt distributed transaction 5.4.426183
01591. 00000 -  "lock held by in-doubt distributed transaction %s"
*Cause:    Trying to access resource that is locked by a dead two-phase commit
           transaction that is in prepared state.
*Action:   DBA should query the pending_trans$ and related tables, and attempt
           to repair network connection(s) to coordinator and commit point.
           If timely repair is not possible, DBA should contact DBA at commit
           point if known or end user for correct outcome, or use heuristic
           default if given to issue a heuristic commit or abort command to
           finalize the local portion of the distributed transaction.

I did Google around and got some help to resolve this. Here are the steps I followed to fix this issue. 
1) Connect to Oracle as sysdba by using this command -- sqlplus sys as sysdba

2) select LOCAL_TRAN_ID from dba_2pc_pending
This above select command will give you list of all pending transaction ids and one id will match with the id mentioned in the above error. you have to pick that id and delete it. Before attempting to delete (step 5) you need to first execute steps 3 and 4. 

3) alter system enable distributed recovery;
   Above statement enables distributed recovery

4) rollback force '5.4.426183';
    commit;
 Note - Use ROLLBACK statement with the FORCE option and a text string that indicates either the local or global transaction ID of the in-doubt transaction to commit.

5) execute dbms_transaction.purge_lost_db_entry('5.4.426183');

Once the above procedure executes successfully then you may try your original Alter/DDL command and restart your app server.

Popular Posts