52

Magento 2 use phpunit framework for running test. You can run test per type and module with command: {phpunit_executable} -c {Magentoroot}/dev/test/{type}/phpunit.xml[.dist] path/to/module/test/dir For example: to run unit test for Catalog, you need run command vendor/phpunit/phpunit/phpunit -c dev/tests/unit/phpunit.xml.dist app/code/Magento/Catalog/...


17

We are using the EcomDev_PHPUnit extension which allows you to test almost everything in Magento without modifying any core files. I recommend the dev branch which is currently more stable than the master. We also have experience with Mage-Test, but can not recommend it, because it overwrites some core files in the community codePool.


17

Using the bundled PHPUnit version, even if it's ancient, is probably the best way to go since that will allow running the tests for all modules together during CI. I think writing tests in a manner that is incompatible with the bundled test framework greatly reduces the value of the tests. Of course you could set up CI to run your tests with a different ...


15

kandy's answer seams like the way to go, but in the mean time I found a quick and dirty way to do it. Copy dev/tests/unit/phpunit.xml.dist to dev/tests/unit/phpunit.xml and replace <directory suffix="Test.php">../../../app/code/*/*/Test/Unit</directory> with <directory suffix="Test.php">../../../app/code/[Namespace]/[Module]/Test/...


15

This is a great thread, and I really like both Answers from @KAndy and @fschmengler. I would like to add some additional thoughts that I find valuable when asking a question such as "Should I test X?" or "How should I test X?". What could go wrong? I could make a dumb typo (happens all the time) This usually doesn't justify writing a test. Will I copy ...


14

Check out PHPSpec with MageSpec if you want something not based on PHPUnit, but with some Magento Integration. Its usable, but not just quite ready for prime time. For mocking PHPSpec 2 uses Prophecy (which is great), but doesn't like magic getters and setters at all. For that reason its better to use Mockery instead, which works fine (and I also like it a ...


13

Installation Since Magento 1 doesn't use composer out of the box, I don't think it makes a big difference if you install phpunit using composer or just download the phar version. If you already use composer to manage other third party modules or libraries in your site, then composer probably makes the most sense. Unless you use PHP7 you will be limited to ...


12

I may be wrong here, but I think for unit tests you don't have to retrieve values from the data base. You can assume that the implementations of \Magento\Framework\App\Config\ScopeConfigInterface are tested and work properly. You only have to test your method that uses getValue from the ScopeConfigInterface. For example, if you have a method like this: ...


11

The short answer is, yes, I would mock the entire Context class. $mockScopeConfig = $this->getMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); $mockContext = $this->getMock(\Magento\Framework\App\Helper\Context::class, [], [], '', false); $mockContext->method('getScopeContext')->willReturn($mockScopeConfig); $classUnderTest = ...


10

I faced the same problem a while back. I considered using the Ecomdev PHPUnit module but I find it hard to use and poorly documented (but I still love what Ivan does and his great contribution to the Magento ecosystem). So, with the help of Vinai, I ended up developping the following test framework module: https://github.com/digitalpianism/testframework ...


8

You can use in your unit test an instance of \Magento\Framework\TestFramework\Unit\Helper\ObjectManager. /** * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */ protected $objectManager; public function setUp() { parent::setUp(); ....//your mocks go here $this->objectManager = new \Magento\Framework\TestFramework\Unit\...


8

TL;DR You are using the getCollectionMock() method correctly. The problem is that it only mocks the getIterator() method. Your code however calls toOptionArray() on the collection, not getIterator(). Because the collection is a mock, by default all its methods only return null, (including toOptionArray()). That is why your test fails with a null as the ...


8

The problem lies in this line in setUp: $this->requestMock->method('getHeader')->willReturn($this->httpHeader); Here you instruct the request mock to return your HttpHeaderInterface mock all the time. Later, in the test, you write $this->requestMock ->expects($this->atLeastOnce()) ->method('getHeader') ...


7

You can test your class like this: public function testSomething() { $contextMock = $this->getMockBuilder(\Magento\Framework\App\Helper\Context::class) ->disableOriginalConstructor() ->getMock(); $productImageFactoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\ImageFactory::class) ->...


6

there is no need. just run phpunit it wil find the phpunit.xml.dist(as fallback) automatically and use the configuration in this file.


6

I think this is the neewst available documentation: http://www.ecomdev.org/wp-content/uploads/2011/05/EcomDev_PHPUnit-0.2.0-Manual.pdf In the current version EcomDev_PHPUnit ships with a phpunit.xml.dist. Rename this one to phpunit.xml, make modifications if necessary and then simply execute phpunit without parameters.


6

You should distinguish between unit and integration tests. Unit Test In a unit test the class under test should get the order data from a collaborator that you can inject as a mock, for example the OrderRepositoryInterface. Integration Test If you want to get test order data from the database, consider writing an integration test instead of a unit test....


6

In my opinion, there is no general answer to "write unit tests for source models, yes or no" I've written unit tests for source models, but those were dynamic source models that fetched external data and there it makes total sense. For source models that are nothing more than glorified arrays (as in your example), I would not bother writing unit tests. But ...


6

Given the information you posted, I suspect that the class \Custom\Shipping\Helper\Config implements (or inherits) public function __call() from a parent class and that the method getProductTypes() is not a real method but rather a "magic getter". Magic methods have to be explicitly specified on generated test doubles, otherwise they can not be stubbed ...


5

The best I can suggest for now is reading up on PHP Unit and looking at other test scripts provided with the code base. I do not recall more unit testing examples being high on the doc teams list at the moment. Some other reading that might be useful. There are lots of unit tests in the Magento 2 code base, such as https://github.com/magento/magento2/blob/...


5

I also like to ensure that the observer is in fact called when doing an appropriate action, e.g. when you dispatch a catalog_product_save_after, then do something like: // initialize $mock as your observer $mock->expects($this->once()) ->method('catalogProductSaveAfter') ->will($this->returnSelf()); // the observer usually returns ...


5

I was able to fix it by putting "default" in front of the fixture value, so the yaml looks like this: config: default/payment/mymodule/numdays: 5 Comments on whether I am supposed to add this prefix are very welcome.


5

Based on updates above, it looks like the original asker solved their problem by Solution or temporary solution: I had to add require_once '../app/code/core/Mage/Core/Model/Factory.php'; require_once '../app/Mage.php'; as the first lines of ../shell/ecomdev-phpunit.php Which made it work fine. I am not sure if it is right or wrong ...


5

The easiest way to deal with that is to run compilation before running tests: bin/magento setup:di:compile The other way is to explicitly define methods for the factory mock eg. instead of doing this: $someFactoryMock = $this->getMockBuilder('Vendor\Module\Model\SomeFactory') ->disableOriginalConstructor() ->getMock(); Do this: $...


5

The problem originates from PHPUnit mocking library, as it cannot autoload the needed class. If you take a look into Magento dev repo, it setups Autoloader catcher, that generates a class when it is requested. If you create similar bootstrap file in your module repository it will work quite well: https://github.com/magento/magento2/blob/develop/dev/tests/...


5

How should I unit test those? I think you should not. Add code to system increase support and maintenance cost but testing process should be LEAN. More over this code should not exists. I believe than in Magento should be one generic declarative way to define sets of options to use in different places. And your reluctance of writing test for this class ...


5

Instantiating the class under test Unit tests should be a simple as possible because that helps with understanding the code being tested as well as debugging. Lets have a look at the purpose of the \Magento\Framework\TestFramework\Unit\Helper\ObjectManager. In effect, all it does is create simple dummies automatically. A complex wrapper like that is ...


5

In addition to @raphael-at-digital-pianism's great response. I find the resolve method rather complex, so I would want test coverage. $inputParams = $this->serviceInputProcessor->process( \Magento\Catalog\Api\CategoryRepositoryInterface:class, 'save', $args ); $result = $this->categoryRepository->save($inputParams[0]); return $result; ...


5

The error probably is caused by some other test initializing an object with the object manager during construction, which is trying to mock the arguments. This shouldn't happen unless the tests actually are being executed. Given the code and the command you posted, the error is not on your side. Workaround If you only want to run a single test class, it is ...


4

Magento has released the Magento Test Automation Framework with tests for CE 1.7.0.2 and it was also used by the community during the March 2013 bugathon where the CE 1.8 alpha was worked on by community developers. I would suggest checking out the official MATF before attempting to use one of the community ports of the Magento 2.0 test suite, all of which ...


Only top voted, non community-wiki answers of a minimum length are eligible