Magento: Tips and tricks how to test Unirgy Dropship module with EcomDev PHPUnit

Tweet about this on TwitterShare on LinkedInShare on Google+Share on FacebookEmail this to someone

A couple of months ago I had a really interesting and very importatnt task. I had to code an automated process that creates Unirgy_DropshipPo purchase orders (Unirgy_DropshipPo_Model_Po objects). Because the task had a very high business value and everything had to work flawlessly, I decided to invest more energy and time in order to write a good test coverage with phpunit. I also knew that I needed tests because there was a big chance my code would be modified in the following weeks because of the business dynamics. I decided to “step” on something that I already knew how to utilise – EcomDev_PHPUnit ( Thank you Ivan Chepurnyi ).

Initially, my idea was to use EcomDev_PHPUnit only as a unit-testing tool and to test functions in isolation, but at a later stage of the development I found out that it would be even better if I used EcomDev_PHPUnit to test different branches of my algorithm.

During the development phase I had 3 main technical challenges:

  1. Unknown / Unexpected behaviour of Unirgy Dropship
  2. Collecting fixtures data in order to simulate test cases close to production environment
  3. Querying the database in order to prove that entities have been modified or created (Purchase order, credit memos and etc.)


1. Unknown / Unexpected behaviour of Unirgy Dropship

I was writing tests but at one moment I couldn’t continue because some of my tests were constantly failing.

The error message of the failing tests was: Unirgy_SimpleLicense_Exception: Module record not found: Unirgy_DropshipPo

The problem was coming from the fact that the Unirgy Dropship module has a license protection. While I was performing the test that invokes a method of some of the ionCube encoded classes (e.g. Unirgy_DropshipMulti_Helper_Protected) the Unirgy Dropship module was trying to do a license validation check (in my case the license validation check was failing). In the beginning it wasn’t so obvious to me because the error message / the exception was fired from ionCube protected class and couldn’t see from where it was trying to get the message “Module record not found: Unirgy_DropshipPo” from. I enabled SQL queries logging during the execution of the tests and found that Magento is trying to access 2 database tables that I wasn’t familiar with – usimplelic_license and usimpleup_module. In order to find a workaround for this license check, I had to copy the data of the 2 database tables (usimplelic_license and usimpleup_module) from my Magento to the phpunit database.

2. Collecting fixtures data in order to simulate test cases close to production environment:

Something that I really like in EcomDev_PHPUnit is the feature to store fixtures data in YAML files. The data from the YAML files is inserted in a separated phpunit database. This database is used only in the context of unit testing. I know that many developers disagree with the approach of storing fixtures data in the database and they will say that this is not unit testing. But we all know how highly coupled Magento is and for me personally this feature comes really handy.

Basically, it works like this:

  1. You store fixtures data in a YAML file.
  2. The data from the YAML file is inserted in a test database each time when you run test that is configured to use fixtures.
  3. After the test completes, EcomDev_PHPUnit truncates the tables used for the current test.

While I was testing different application branches, I used fixtures from a huge YAML file for the following tables:

eav:
  catalog_product:
    - entity_id: example-product-id
      type_id: simple
      …

tables:
  sales/order:
    - entity_id: example-order-id
      state: "processing"
      …

  sales/order_address:
    - entity_id: example-order-address-id
      …

  sales/order_item:
    - item_id: example-order-item-id
      …

  sales/order_payment:
    - entity_id: example-order-payment-id
      …

  sales/invoice:
    - entity_id: example-invoce-id
      …

  sales/invoice_item:
    - entity_id: example-invoce-item-id
      …

  udpo/po:
    - entity_id: example-purchase-order-id
      …

  udpo/po_item:
    - entity_id: example-purchase-order-item-id
      …

  udropship/vendor:
    - vendor_id: example-udropship-vendor-id
      …

  udropship/vendor_product:
    - vendor_product_id: example-udropship-vendor-product-id
      …

  cataloginventory/stock_item:
    - item_id: example-stock-item-id
      …

As you can see, I used fixtures for 11 flat tables and some extra fixture data for catalog_product entities. Preparing all these fixtures was a lot of work but in the end I had the flexibility to test different business cases. Even more, I was able to easily convert live data to fixtures and recreate buggy behaviour.

3. Querying the database in order to prove that entities have been modified or created (Purchase order, credit memos and etc.):

Because of the specifics of Unirgy Dropship e.g. the ionCube protected classes I couldn’t mock so easily and test if an entity has been modified or created. I decided to query the database in order to check what is the outcome of the invoked functions from the ionCube protected class. Basically, the tests cases where I wanted to check if new purchase orders had been created were completing with something like this:

$collection =  Mage::getModel('udpo/po’)->getCollection();
$this->assertEquals(3, count($collection));

Your thoughts / questions?

Tweet about this on TwitterShare on LinkedInShare on Google+Share on FacebookEmail this to someone

Tsvetan Stoychev

Tsvetan aka. Cecko is the founder of Cecko's Lab. He is Magento addicted since Magento CE 1.2.1.2 and has worked on over 30 Magento projects. At the moment he is in charge to take care about the money flow of the company, to keep constant communication with the clients and to keep the people in the office busy.

More Posts

Follow Me:
TwitterLinkedIn

  • Dusan Lukic

    Very interesting topic. Could you maybe share some of the actual tests that you wrote?

  • ceckoslab

    I can try, but I have first to ask for permission and the answer is YES, then I have to do some cleanup in the code, because it may contain business sensitive data.

  • Christoph Massmann

    Cool – really interesting & thanks for sharing!

  • ceckoslab

    Hi Dusan Lukic

    It’s too much bureaucracy to try to manage the example code, so unfortunately I can’t show the actual tests, but I can do something else …

    I will share with you from where I was looking in favor to learn to use EcomDev_PHPUnit.

    Please take a look at these repositories and what the developers have put in their test folders:

    https://github.com/EcomDev?tab=repositories
    https://github.com/Vinai?tab=repositories
    https://github.com/avstudnitz/AvS_FastSimpleImport

    Hope that helps.

  • Dusan Lukic

    Hi, thanks a lot for the comment, it is helpful. I basically wanted to see how it looks like in a real life case, I remember I played with it a year ago but I never got the chance to use it on real project.

    Thanks again anyway, it is a great topic indeed.