Mais conteúdo relacionado


Introduction to Integration Tests in Magento / Adobe Commerce

  1. Introduction to Integration Tests in Magento / Adobe Commerce Bartosz Górski
  2. Automated test types in Magento / Adobe Commerce ● Unit Tests ● Integration Tests ● Functional Tests (MFTF) ● API Functional Tests ● Static Tests ● …and more Full list of supported test types:
  3. Integration Tests - basic info ● Very similar to Unit Tests in architecture ● Based on PHPUnit ● Use the built-in Integration Tests Framework ● Require access to services that Magento requires for installation (database, redis, search engine etc.) ● Require some initial setup in config files
  4. Integration Tests - types We can identify two types of Integration Tests: - End-to-end or cross-component tests: tests that simulate full path of some use case, like registering a customer, adding a product to cart, filling shipping and billing data, placing an order and checking if it got persisted in the database with no errors - Component tests: tests that usually involve only one class along with its dependencies; something that a lot of people would consider a Unit Test for
  5. Setting up 1. Create an empty database 2. Copy two .dist files in dev/tests/integration/etc/ to the same directory, but without the .dist extension: a. install-config-mysql.php.dist b. config-global.php.dist 3. Edit your new install-config-mysql.php file and adjust all the settings for database connection, redis connection etc. 4. Do not touch admin credentials or frontname as some tests may fail because of that 5. If you have any global config settings that all your tests require, put them in config-global.php 6. Copy dev/test/quick-integration/phpunit.xml.dist to dev/tests/quick-integration/phpunit.xml and disable TESTS_CLEANUP to speed up subsequent executions (the app won’t try to reinstall) Run your tests using the following command from the Magento dev/tests/integration directory: php ../../../vendor/bin/phpunit ../../../some/directory/to/test
  6. Anatomy of a test This is how a simple Integration Test looks like:
  7. Integration Tests Framework - Annotations The following annotations are available in integration tests: ● @magentoAppIsolation ● @magentoDbIsolation ● @magentoDataFixture ● @magentoDataFixtureBeforeTransaction ● @magentoAppArea ● @magentoConfigFixture There are less commonly used ones too, the full list is available here:
  8. Annotations - Example Please note that there are two different ways of defining a data fixture: ● The first one defines a path relative to a module ● The second one defines a path relative to dev/tests/integration/testsuite There are tons of useful fixtures in dev/tests/integration/testsuite.
  9. Integration Tests vs Unit Tests Unit Tests Integration Tests Dependent on tested code implementation Independent of implementation - they only care about results Require A LOT of mocks Don’t require mocks - can work with “real” classes. Can still use mocks if required. Require a lot of maintenance effort Don’t require a lot of maintenance effort Can only work with PHP classes Can also test validity of the XML-based configuration layer Can only test in isolation Can test in as much isolation as the developer wants Hard to predict during a task creation Can be easily defined as parts of acceptance criteria Run VERY fast Run VERY slow* Limited possibility of testing code that interacts with 3rd party services Limited possibility of testing code that interacts with 3rd party services* * Can be improved
  10. Integration Tests vs Unit Tests - let’s talk numbers… Customer repository - unit test class Customer repository - integration test class 82 lines of setUp() 15 lines of setUp() 173 lines of testSave() 20 lines of testCreateNewCustomer() which also tests save(); No need for an explicit testSave() 57 mocks in the class 0 mocks in the class, only actual test logic 742 lines of code in the class for 5 tests: delete, deleteById, getList, save and saveWithPassworHash 692 lines of code to perform 14 different tests mocks returning mocks all objects created by the object manager
  11. Integration Tests vs Unit Tests - a unit test
  12. Integration Tests vs Unit Tests - an integration test
  13. Example of how to define tests during task creation Task #1: Admins should see ERP invoice issuer on the invoice view page in Magento admin panel Description: When an invoice is manually created in ERP, it has the creator’s name attached. We are already pulling this data and now we need to show it in Magento admin panel. Invoices that have this data should display “Issuer: Name Here” and those that don’t should not display this info at all. Tests: easy to define both Unit and Integration tests during the task creation, as this will require a template override and either a ViewModel or a preference for the block to pull the data from the database.
  14. Example of how to define tests during task creation Now imagine that the initial implementation of the Task #1 example was made using a preference for the block displaying this data, but later on it got refactored to a view model. Integration tests will still work.
  15. Example of how to define tests during task creation Task #2: Customers can’t place orders above $10,000 Description: No customer is able to place an order above $10k. Those same customers can successfully place orders below or equal $10k with the same data (addresses, shipping and billing method etc.). Integration Tests: Create a quote for above $10k, use it to place orders. Watch it fail, then fix the issue. Unit Tests: ???
  16. Integration Tests - issues and how to avoid them Two main issues are: ● Long execution time ● Limited help with testing code that connects with 3rd party services Solution: ReachDigital Magento 2 Performance tuned integration tests
  17. Integration Tests - with the ReachDigital component Fix for the issue #1 - long execution time: ● Disabled memory cleanup scripts ● Made the application to not reinitialize that much ● Disabled config-global.php usage ● Disabled the sequence table generation It takes just seconds to run a single test.
  18. Integration Tests - with the ReachDigital component Fix for the issue #2 - limited possibility of testing code that interacts with 3rd party services: ● Introduced TestModules ● Every module can have a TestModule directory inside with a fully functional Magento module ● Those modules are copied to app/code during tests execution and don’t affect regular (non-test) executions of the Magento application ● Test modules can have preferences and/or around plugins in di.xml for classes/methods that connect to 3rd party services, and return mocked data instead ● Limitation: works only for modules inside the vendor directory
  19. Integration Tests - with the ReachDigital component Setting up: 1. composer require --dev reach-digital/magento2-test-framework 2. Perform the regular setup procedure for integration tests 3. Copy dev/tests/quick-integration/phpunit.xml.dist to dev/tests/quick- integration/phpunit.xml if you need to change anything there Running: Perform the following commands from the Magento root directory: cd dev/tests/integration php ../../../vendor/bin/phpunit -c ../quick-integration/phpunit.xml ../../../path/to/test
  20. Conclusions 1. Do test your code 2. Use Integration Tests instead of Unit Tests for better results 3. Consider end-to-end tests for critical paths 4. Use component integration tests for your modules 5. Install the ReachDigital component or else you’ll get bored and abandon the idea of running Integration Tests
  21. Questions?
  22. Thank You! If you have any questions or just want to connect: Email: LinkedIn: