FitNesse Book and Improvement

Automated Testing Tools are used to assure modifications are always backward compatible and safe for production
Forum rules
This forum is personally pruned to avoid redundant posts. Related topics are moved to the same sub-forum. Language will be corrected for readability.

FitNesse Book and Improvement

Postby red1 » Sun Sep 20, 2015 8:23 pm

You can read an online book still in progress here http://red1.org/iDempiereFitNesse.pdf
The improvement to roll back or commit option is made as a plugin and described here http://wiki.idempiere.org/en/Plugin:_FitNesse_RollBack. It includes https://idempiere.atlassian.net/browse/IDEMPIERE-2859 patch.
To use it, just install the linked fixture plugin, and start it, without starting the other fixture plugin.
You may submit any comments, suggestions for improvements or contribution to improve in this forum.
This work is under the auspices of SYSNOVA, Bangladesh who sponsors most of my contributions and testing effort.
red1
Site Admin
 
Posts: 2670
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Create Record Auto

Postby red1 » Sun Sep 27, 2015 2:21 am

More goodies. I made a new Fixture to handle 'Create Record Auto' which will try to create your table record without entering any data setting! This assume that you want to test if your table can be populated as full as possible at will, saving you the tedious task of putting in every column data. This is even more useful when you just created a new table and want to quickly test it.

However I made a cooler thing that you can add more specific rows setting as usual under that within the same CreateAutoRecord template in order to control any field value!

Just check the new CreateRecordAuto.java in the patch at http://sourceforge.net/projects/red1/files/Testing/. Use the jar plugin to replace the one already in iDempiere to get these cool features.
Note below how the CreateAutoRecord only needs an empty line to make it work. So you can go lazy or half lazy with this. Then after that, other templates are usable as seen below.

CreateRecordAuto.png
CreateRecordAuto.png (47.92 KiB) Viewed 2443 times
When tested, everything goes well.

AutoFixtureResults.png
AutoFixtureResults.png (85.13 KiB) Viewed 2443 times
Below we see a pristine example where i am able to test a new Forecast master-detail set with blank row line in each table, and just pass the parent ID over. The processing of it also returned 1 extra making it 51 new PO forecastlines as compared to 50 proven elsewhere.

ForecastMasterDetail.png
ForecastMasterDetail.png (73.89 KiB) Viewed 2434 times
red1
Site Admin
 
Posts: 2670
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Copy Paste Script

Postby red1 » Sun Sep 27, 2015 2:30 am

You can collect these snips to paste in your Fixture story script easily:
For super easy and new table record creation
Code: Select all
!|Create Record Auto|
|*Table*  |C_Order|
|||
|*Save*   |           |
Remember, you can add more rows of specific data setting below that blank line! But in this case the C_Order just works. For example if you need to make sure it is a POS Order then just add that extra line (currency id needed to be specific too):

Code: Select all
|*Table*  |C_Order|
|||
|c_doctypetarget_id    |@Ref=c_doctype[Name='POS Order'].c_doctype_id|
|C_Currency_id        |100                                         |
|*Save*   |           |

For rolling back
Code: Select all
!|Roll Back|
|*RollBack*|TRUE|

In case you want to commit
Code: Select all
!|Roll Back|
|*Commit*|TRUE|
red1
Site Admin
 
Posts: 2670
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: FitNesse Book and Improvement

Postby red1 » Sun Sep 27, 2015 3:16 am

Important code snippets:
Code: Select all
/**
    * returning back the cell_value from the column name (cell_title)
    * @param col
    * @param trxName
    * @return
    * @throws SQLException
    */
   private String getColumnValue(MColumn col, String trxName) throws SQLException {
      Integer value;
      String name = col.getColumnName();
      //determine if column is mandatory to fill in and not 7 compulsory fields
      if (name.equals("AD_Client_ID")||name.equals("Created")||name.equals("CreatedBy")||name.equals("Updated")||name.equals("UpdatedBy")||name.equals("IsActive"))
         return null;
      if (name.endsWith("_UU"))
         return null;   
      if (name.equals("AD_Org_ID"))
         return "11";
      
      //
      if (name.endsWith("_ID")) {
         String tablename = name.substring(0, name.indexOf("_ID"));
         MTable table = new Query(Env.getCtx(),MTable.Table_Name,MTable.COLUMNNAME_TableName+"=?",trxName)
         .setParameters(tablename)
         .first();
         if (table==null)
            return null; //table does not exist
         PreparedStatement pstmtReferenceId = null;
         ResultSet rs = null;
         try
         {
             pstmtReferenceId = DB.prepareStatement("SELECT "+tablename+"_ID FROM "+tablename, trxName);
              rs = pstmtReferenceId.executeQuery();
             if (rs.next()){
               value = rs.getInt(1);
               return value.toString();
            }
         }
         catch (SQLException e)
         {
            e.printStackTrace();
            return null;
         }
         finally
         {
            DB.close(rs, pstmtReferenceId);
            rs = null; pstmtReferenceId = null;
         }

      }else {
         int datatype = col.getAD_Reference_ID();
         if (datatype==10 || datatype==14) //string / text
            return "@random_string(Auto,,6)";
         if (datatype==11) //Integer
            return "@random_number(,,2)";
         if (datatype==15 || datatype==16) {//datetime
            Timestamp date = new Timestamp (System.currentTimeMillis()); //present now
            return date.toString();
         }
         if (datatype==20){//Yes/No
            return "Y";
         }
         System.out.print(datatype);
      }
      //will have no row setting - bypassed
      return null;
   }

   private List<MColumn> getTableColumns(String tableName, String trxName) {
      MTable table = new Query(Env.getCtx(),MTable.Table_Name,MTable.COLUMNNAME_TableName+"=?",trxName)
      .setParameters(tableName)
      .first();
      List<MColumn> adCols = new Query(Env.getCtx(),MColumn.Table_Name,MColumn.COLUMNNAME_AD_Table_ID+"=? AND "
            +MColumn.COLUMNNAME_ColumnName+"!=?",null)
      .setParameters(table.get_ID(), tableName+"_ID")
      .list();      
      return adCols;
   }


Code: Select all
         } else {
            if (tableOK) {
               //TODO create an array to pass to cell_title and cell_value from AD automatically
               if (cell_title.isEmpty()){
                  List<MColumn> cols = getTableColumns(tableName,trxName);
                  for (MColumn col:cols){
                     cell_title = col.getColumnName();
                     try {
                        cell_value = getColumnValue(col, trxName);
                     } catch (SQLException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                     }
                     if (cell_value==null) continue;
                     //original snip
                     columnName = cell_title;
                     int idxcol = gpo.get_ColumnIndex(columnName);
                     if (idxcol<0) continue;
                     columnsOK = doOriginalLoop(ctx, windowNo, trxName, gpo,
                           columnName, columnsOK, isErrorExpected,
                           msgerror1, table, poinfo, i, cell_title,
                           cell_value, idxcol);
                  }
               }
               else {
                  columnsOK = doOriginalLoop(ctx, windowNo, trxName, gpo,
                        cell_title, columnsOK, isErrorExpected,
                        msgerror1, table, poinfo, i, cell_title,
                        cell_value, gpo.get_ColumnIndex(cell_title));
               }
            }   
red1
Site Admin
 
Posts: 2670
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: FitNesse Book and Improvement

Postby red1 » Mon Sep 28, 2015 3:36 pm

Now I add another follow through test to Generate POs from the PO FOrecasts and here are the results:

GenerateForecastPOs.png
GenerateForecastPOs.png (48.05 KiB) Viewed 2405 times
Note that the POs are consolidated to respective vendors and returned message of success.

I also renamed all packages to be unique to individual plugin project on advice from Hiep LQ to avoid name clash in future from other future new plugins. I have reissued fresh 2Packs and pushed all code changes to respective bitbucket repos.
red1
Site Admin
 
Posts: 2670
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: FitNesse Book and Improvement

Postby red1 » Tue Sep 29, 2015 2:48 pm

Another big improvement to the testing arsenal that now includes Info Window!

Screen Shot 2015-09-29 at 1.41.00 AM.png
Screen Shot 2015-09-29 at 1.41.00 AM.png (46.76 KiB) Viewed 2398 times
Now any InfoWindow can be tested! Just specify the Info Window name in the first box and then specify its associated InfoProcess using the same Run Process box and it will pick up the first record derived from the InfoWindow. This can effectively test generically that Info Window itself, the defined SQL and WHERE clauses execution is working with its passing via PInstance into T_Selection table to successfully pick up the trail and when processed, returns the result output to the test.
red1
Site Admin
 
Posts: 2670
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: FitNesse Book and Improvement

Postby red1 » Wed Oct 21, 2015 12:20 am

New test script underway specifically for Libero Manufacturing based on test plan contributed by SYSNOVA, Bangladesh uploaded here SysnovaLiberoTestPlan PDF.
Results of first set of test:

Screen Shot 2015-10-20 at 11.18.59 AM.png
Screen Shot 2015-10-20 at 11.18.59 AM.png (72.3 KiB) Viewed 2247 times

READ TO CONFIRM DATA IS PRESENT BEFORE FURTHER TESTS

!include -c AaAdminLogin

!|Read Record|
|*Table* |PP_Product_BOM |
|PP_Product_BOM_ID |@Ref=PP_Product_BOM[Value='Fertilizer'].PP_Product_BOM_ID|
|*Read* | |
|Name||

UPDATE CURRENTCOSTPRICE FOR LABOR OF FERTILIZER
!|Update Record|
|*Table*|M_Cost|
|*WHERE*|M_CostElement_ID=105 AND M_Product_ID = 50025|
|*Update*||
|CurrentCostPrice|15|

UPDATE CURRENTCOSTPRICE FOR OVERHEAD OF FERTILIZER
!|Update Record|
|*Table*|M_Cost|
|*WHERE*|M_CostElement_ID=50001 AND M_Product_ID = 50025|
|*Update*||
|CurrentCostPrice|15|

UPDATE BOMTYPE OF FERTILIZER TO 'MAKE-TO-ORDER'
!|Update Record|
|*Table*|PP_Product_BOM|
|*WHERE*|PP_Product_BOM_ID=50006|
|*Update*||
|BOMType|O|

!|Read Record|
|*Table* |C_bpartner |
|c_bpartner_id |@Ref=c_bpartner[Value='SeedFarm'].c_bpartner_id|
|*Read* | |
|actuallifetimevalue| |
|so_creditused | |
|totalopenbalance | |

Create sales order

!|Create Record|
|*Table* |C_Order |
|ad_org_id |50001 |
|c_doctypetarget_id |@Ref=c_doctype[Name='Standard Order'].c_doctype_id|
|salesrep_id |101 |
|dateordered |2009-03-25 00:00:00.0 |
|c_bpartner_id |@c_bpartner.c_bpartner_id@ |
|c_bpartner_location_id|114 |
|paymentrule |B |
|m_warehouse_id |50002 |
|m_pricelist_id |101 |
|ad_user_id |105 |
|*Save* | |

!|Create Record|
|*Table* |C_OrderLine |
|c_order_id |@C_order.c_Order_id@ |
|ad_org_id |@C_Order.AD_Org_ID@ |
|m_product_id|@Ref=M_Product[Value='Fertilizer'].M_Product_ID|
|qtyentered |2 |
|qtyordered |2 |
|*Save* | |

Complete the sales order
!|Run Process|
|*ProcessValue*|C_Order Process |
|*RecordID* |@C_Order.C_Order_ID@|
|*DocAction* |CO |
|*Run* | |

CALCULATE MATERIAL PLAN
!|Run Process|
|*ProcessValue*|PP_Calculate Material Plan |
|AD_Org_ID |@Ref=AD_Org[Value='Fertilizer'].AD_Org_ID|
|S_Resource_ID|@Ref=S_Resource[Value='Fertilizer Plant'].S_Resource_ID|
|M_Warehouse_ID|@Ref=M_Warehouse[Value='Fertilizer'].M_Warehouse_ID|
|*Run* | |

!|RollBack|
|*RollBack*|TRUE|
red1
Site Admin
 
Posts: 2670
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia

Re: FitNesse Book and Improvement

Postby red1 » Wed Jun 07, 2017 8:49 am

The source is now committed to http://bitbucket.org/red1/org.idempiere ... se.fixture for use in developer IDE environment.
(Didn't realised it was not, and the patch submitted to JIRA is not complete as its missing the ReadInfoWindow method.)

I did a distinctive improvement to Read Info Window as used in the new WMS.

FitNesseTest.png
FitNesseTest.png (69.19 KiB) Viewed 391 times
Now it will iterate all records in the Info-Window. However the criteria columns are not in play thus we can use arbitrary WHERE clause to do so and restrict further. Note the IsSOTrx='N' to ensure only Purchase Orders are obtained. You can have multiple WHERE rows. If there is already a WHERE Clause in the Info-Window, it is already appended and you need not repeat it.

Thus this Read Info Window truly tests the SQL and WHERE as well as the Process attached. However you have to call the Process as usual under Run Process. The test script you can copy paste from:

Code: Select all
!include -c LogInto

!|ReadInfoWindow|
|*InfoWindow*|Orders to Delivery Schedule|
|*WHERE*|b.IsSOTrx='Y'|

!|RunProcess|
|*ProcessValue*|CreateDeliverySchedule|
|WM_Gate_ID|1000001|
|*Run*||

!|ReadInfoWindow|
|*InfoWindow*|Delivery Schedule to Putaway/Picking|

!|RunProcess|
|*ProcessValue*|CreatePutawayList|
|WM_HandlingUnit_ID|1000000|
|IsSameLine|Y|
|*Run*||

!|RollBack|
|*Commit*|True|

Log Into include:

Code: Select all
!|Login|
|User        |GardenAdmin|
|Password    |GardenAdmin|
|AD_ClIEnT_id|@Ref=AD_Client[Value='GardenWorld'].AD_Client_ID|
|AD_Role_id  |@Ref=AD_Role[Name='GardenWorld Admin'].AD_Role_ID        |
|*Login*     |           |
red1
Site Admin
 
Posts: 2670
Joined: Tue Jul 06, 2004 3:01 pm
Location: Kuala Lumpur, Malaysia


Return to Quality Assurance

Who is online

Users browsing this forum: No registered users and 1 guest

cron