+ All Categories
Home > Technology > Odoo testing on steroids

Odoo testing on steroids

Date post: 07-Aug-2015
Category:
Upload: camptocamp
View: 50 times
Download: 1 times
Share this document with a friend
52
odoo testing on steroids Leonardo Pistone Camptocamp 1 / 52
Transcript

odoo testing on steroidsLeonardo Pistone

Camptocamp

1 / 52

About me

Leonardo Pistone

Developer @ CamptocampOCA committer & delegate member@lepistone

2 / 52

what I'd love

3 / 52

def test_no_price_no_tax(self): assert compute_tax(0) == 0

4 / 52

def test_no_price_no_tax(self): assert compute_tax(0) == 0

def compute_tax(base, rate=0): return 0

5 / 52

def test_no_price_no_tax(self): assert compute_tax(0) == 0

def compute_tax(base, rate=0): return 0

def test_zero_rate(self): assert compute_tax(50, 0) == 50

6 / 52

def compute_tax(base, rate=0): return base

def test_no_price_no_tax(self): assert compute_tax(0) == 0

def test_zero_rate(self): assert compute_tax(50, 0) == 50

7 / 52

def compute_tax(base, rate=0): return base

def test_no_price_no_tax(self): assert compute_tax(0) == 0

def test_zero_rate(self): assert compute_tax(50, 0) == 50

def test_positive_rate(self): assert compute_tax(100, 0.05) == 105

def test_negative_rate(self): assert compute_tax(100, 0.05) == 95

8 / 52

def compute_tax(base, rate=0): return base * (1 + rate)

def test_no_price_no_tax(self): assert compute_tax(0) == 0

def test_zero_rate(self): assert compute_tax(50, 0) == 50

def test_positive_rate(self): assert compute_tax(100, 0.05) == 105

def test_negative_rate(self): assert compute_tax(100, 0.05) == 95

9 / 52

# python -m unittest discover

....---------------------Ran 4 tests in 0.002s

OK

10 / 52

# python -m unittest discover

....---------------------Ran 4 tests in 0.002s

OK

$ python -m unittest discover

F.F.======================================================================FAIL: test_positive_rate_increases_amount (test_tax.TestTax)----------------------------------------------------------------------Traceback (most recent call last): File "tdd/test_tax.py", line 13, in test_positive_rate_increases_amount self.assertEqual(compute_tax(100, 0.05), 105)AssertionError: 100 != 105

----------------------------------------------------------------------Ran 4 tests in 0.000s

FAILED (failures=2)

11 / 52

expressive

12 / 52

expressive

fast

13 / 52

expressive

fast

relevant output

14 / 52

expressive

fast

relevant output

maintainable

15 / 52

expressive

fast

relevant output

maintainable

¯\_(ツ)_/¯

16 / 52

...really?

17 / 52

2015-03-19 13:24:51,806 23693 INFO openerp_test openerp.addons.sale_exception_nostock.tests.test_dropshipping_skip_check: test_dropshipping_sale_can_always_be_delivered (openerp.addons.sale_exception_nostock.tests.test_dropshipping_skip_check.TestDropshippingSkipCheck)2015-03-19 13:24:51,811 23693 INFO openerp_test openerp.addons.sale_exception_nostock.tests.test_dropshipping_skip_check: test_dropshipping_sale_does_not_affect_future_orders (openerp.addons.sale_exception_nostock.tests.test_dropshipping_skip_check.TestDropshippingSkipCheck)2015-03-19 13:24:51,812 23693 INFO openerp_test openerp.addons.sale_exception_nostock.tests.test_dropshipping_skip_check: Ran 2 tests in 0.006s2015-03-19 13:24:51,812 23693 INFO openerp_test openerp.addons.sale_exception_nostock.tests.test_dropshipping_skip_check: OK2015-03-19 13:24:52,933 23693 INFO openerp_test openerp.modules.module: module sale_owner_stock_sourcing: creating or updating database tables2015-03-19 13:24:53,048 23693 INFO openerp_test openerp.modules.loading: loading sale_owner_stock_sourcing/view/sale_order.xml2015-03-19 13:24:53,155 23693 INFO openerp_test openerp.modules.loading: loading sale_owner_stock_sourcing/security/group.xml2015-03-19 13:24:53,227 23693 INFO openerp_test openerp.modules.module: openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation running tests.2015-03-19 13:24:53,228 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation: test_one_line_with_owner_reserves_its_stock (openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation.TestIntSaleToReservation)2015-03-19 13:24:54,618 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation: test_one_line_without_owner_insufficient_stock_respects_stock (openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation.TestIntSaleToReservation)2015-03-19 13:24:55,716 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation: test_one_line_without_owner_reserves_my_stock (openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation.TestIntSaleToReservation)2015-03-19 13:24:56,809 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation: test_two_lines_one_with_owner_reserves_correct_stock (openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation.TestIntSaleToReservation)2015-03-19 13:24:58,537 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation: Ran 4 tests in 5.309s2015-03-19 13:24:58,537 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation: OK2015-03-19 13:24:58,537 23693 INFO openerp_test openerp.modules.module: openerp.addons.sale_owner_stock_sourcing.tests.test_int_sale_to_reservation tested in 5.31s, 3929 queries2015-03-19 13:24:58,538 23693 INFO openerp_test openerp.modules.module: openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move running tests.2015-03-19 13:24:58,538 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: test_it_propagates_empty_owner_to_the_move (openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move.TestPropagateOwner)2015-03-19 13:24:59,572 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: test_it_propagates_owner_to_the_move (openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move.TestPropagateOwner)2015-03-19 13:24:59,998 23693 ERROR openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: FAIL2015-03-19 13:24:59,999 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: ======================================================================2015-03-19 13:24:59,999 23693 ERROR openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: FAIL: test_it_propagates_owner_to_the_move (openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move.TestPropagateOwner)2015-03-19 13:24:59,999 23693 ERROR openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: Traceback (most recent call last):2015-03-19 13:24:59,999 23693 ERROR openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: ̀ File "/home/travis/build/OCA/sale-workflow/sale_owner_stock_sourcing/tests/test_propagate_owner_to_move.py", line 32, in test_it_propagates_owner_to_the_move2015-03-19 13:24:59,999 23693 ERROR openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: ̀ self.assertEqual(1, len(self.so.picking_ids))2015-03-19 13:24:59,999 23693 ERROR openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: ̀ AssertionError: 1 != 02015-03-19 13:24:59,999 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: Ran 2 tests in 1.462s2015-03-19 13:25:00,000 23693 ERROR openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: FAILED2015-03-19 13:25:00,000 23693 INFO openerp_test openerp.addons.sale_owner_stock_sourcing.tests.test_propagate_owner_to_move: (failures=1)2015-03-19 13:25:00,000 23693 ERROR openerp_test openerp.modules.module: Module sale_owner_stock_sourcing: 1 failures, 0 errors2015-03-19 13:25:01,305 23693 INFO openerp_test openerp.modules.module: module sale_partner_order_policy: creating or updating database tables2015-03-19 13:25:01,459 23693 INFO openerp_test openerp.modules.loading: loading sale_partner_order_policy/partner_view.xml2015-03-19 13:25:01,611 23693 INFO openerp_test openerp.modules.loading: loading sale_partner_order_policy/partner_demo.xml2015-03-19 13:25:01,753 23693 INFO openerp_test openerp.modules.loading: 45 modules loaded in 25.22s, 5043 queries2015-03-19 13:25:03,314 23693 ERROR openerp_test openerp.modules.loading: At least one test failed when loading the modules.2015-03-19 13:25:03,347 23693 INFO openerp_test openerp.modules.module: openerp.addons.base.tests.test_xmlrpc running tests.2015-03-19 13:25:03,348 23693 INFO openerp_test openerp.addons.base.tests.test_xmlrpc: test_01_xmlrpc_login (openerp.addons.base.tests.test_xmlrpc.test_xmlrpc)

18 / 52

(╯°□°)╯︵ ┻━┻)

19 / 52

(╯°□°)╯︵ ┻━┻)

20 / 52

Problems

21 / 52

Problems

output

22 / 52

Problems

output

slowness

23 / 52

Problems

output

slowness

dependencies

24 / 52

Problems

output

slowness

dependencies

brittleness

25 / 52

unittestclass TestItBlocks(TransactionCase): def test_it_can_block(self): self.order.order_line.budget_tot_price = 80.0 self.order.order_line.price_unit = 100.0

self.order.action_button_confirm()

self.assertEqual('draft', self.order.state)

26 / 52

unittestclass TestItBlocks(TransactionCase): def test_it_can_block(self): self.order.order_line.budget_tot_price = 80.0 self.order.order_line.price_unit = 100.0

self.order.action_button_confirm()

self.assertEqual('draft', self.order.state)

def setUp(self): super(TestItBlocks, self).setUp() # boring stuff

27 / 52

YAML- I create a quotation with a dropshipping line.- !record {model: sale.order, id: so_4}: partner_id: base.res_partner_3 order_line: - product_id: product.product_product_7 product_uom_qty: 8 route_id: route_drop_shipping- I confirm the sale order, run the scheduler, and check that the address of the sale order has been propagated to the automatically generated purchase order.- !python {model: sale.order, id: so_4}: | from nose.tools import *

self.action_button_confirm() self.env['procurement.order'].run_scheduler() proc = self.order_line[0].procurement_ids assert_equal( proc.purchase_id.dest_address_id.id, ref('base.res_partner_3'), )

28 / 52

OERPScenarioFeature: Invoice workflow

Scenario: Validation of an invoice Given I entered a supplier invoice for 1000 EUR When I validate the invoice Then the state of the invoice is "open"

29 / 52

OERPScenarioFeature: Invoice workflow

Scenario: Validation of an invoice Given I entered a supplier invoice for 1000 EUR When I validate the invoice Then the state of the invoice is "open"

need to write steps to implement phrases

30 / 52

OERPScenarioFeature: Invoice workflow

Scenario: Validation of an invoice Given I entered a supplier invoice for 1000 EUR When I validate the invoice Then the state of the invoice is "open"

need to write steps to implement phrases

can abstract from implementation

31 / 52

OERPScenarioFeature: Invoice workflow

Scenario: Validation of an invoice Given I entered a supplier invoice for 1000 EUR When I validate the invoice Then the state of the invoice is "open"

need to write steps to implement phrases

can abstract from implementation

same test could be used for backend + browser

32 / 52

OERPScenarioFeature: Invoice workflow

Scenario: Validation of an invoice Given I entered a supplier invoice for 1000 EUR When I validate the invoice Then the state of the invoice is "open"

need to write steps to implement phrases

can abstract from implementation

same test could be used for backend + browser

readable by non-developers

33 / 52

new()class TestUnitCheck(TransactionCase):

def test_over_budget(self): order = self.env['sale.order'].new({ 'total_budget': 80.0, 'amount_total': 100.0, }) self.assertTrue(order.over_budget())

34 / 52

new()class TestUnitCheck(TransactionCase):

def test_over_budget(self): order = self.env['sale.order'].new({ 'total_budget': 80.0, 'amount_total': 100.0, }) self.assertTrue(order.over_budget())

required fields are not enforced

35 / 52

new()class TestUnitCheck(TransactionCase):

def test_over_budget(self): order = self.env['sale.order'].new({ 'total_budget': 80.0, 'amount_total': 100.0, }) self.assertTrue(order.over_budget())

required fields are not enforced

not stored to the database

36 / 52

new()class TestUnitCheck(TransactionCase):

def test_over_budget(self): order = self.env['sale.order'].new({ 'total_budget': 80.0, 'amount_total': 100.0, }) self.assertTrue(order.over_budget())

required fields are not enforced

not stored to the database

otherwise pretty real

37 / 52

mockproduct = Mock( spec_set=self.env['product.product'], qty_available=20,)

38 / 52

mockproduct = Mock( spec_set=self.env['product.product'], qty_available=20,)

fake objects

39 / 52

mockproduct = Mock( spec_set=self.env['product.product'], qty_available=20,)

fake objects

canned responses

40 / 52

anybox.buildout.odoo / nosetests

41 / 52

anybox.buildout.odoo / nosetests$ bin/nosetests_odoo -d d -- -w module_dirINFO ? anybox.recipe.openerp.runtime.session: Opening database 'd'.........

------------------------------------------------------------------Ran 9 tests in 21.794s

OK

42 / 52

anybox.buildout.odoo / nosetests$ bin/nosetests_odoo -d d -- -w module_dirINFO ? anybox.recipe.openerp.runtime.session: Opening database 'd'.........

------------------------------------------------------------------Ran 9 tests in 21.794s

OK

no update

43 / 52

anybox.buildout.odoo / nosetests$ bin/nosetests_odoo -d d -- -w module_dirINFO ? anybox.recipe.openerp.runtime.session: Opening database 'd'.........

------------------------------------------------------------------Ran 9 tests in 21.794s

OK

no update

no irrelevant logging

44 / 52

anybox.buildout.odoo / nosetests$ bin/nosetests_odoo -d d -- -w module_dirINFO ? anybox.recipe.openerp.runtime.session: Opening database 'd'.........

------------------------------------------------------------------Ran 9 tests in 21.794s

OK

no update

no irrelevant logging

rerun only failing tests

45 / 52

anybox.buildout.odoo / nosetests$ bin/nosetests_odoo -d d -- -w module_dirINFO ? anybox.recipe.openerp.runtime.session: Opening database 'd'.........

------------------------------------------------------------------Ran 9 tests in 21.794s

OK

no update

no irrelevant logging

rerun only failing tests

keep your old tests

46 / 52

split decisions and dependencies

47 / 52

split decisions and dependenciesclass Invoice: def compute(amount, rate): # put decisions here return amount * (rate + 1)

48 / 52

split decisions and dependenciesclass Invoice: def compute(amount, rate): # put decisions here return amount * (rate + 1)

def update_tax(self): # put dependencies here tax = Tax.search(self.partner.tax_conditions) self.amount_with_tax = self.compute( self.amount_untaxed, tax.rate, )

49 / 52

split decisions and dependenciesclass Invoice: def compute(amount, rate): # put decisions here return amount * (rate + 1)

def update_tax(self): # put dependencies here tax = Tax.search(self.partner.tax_conditions) self.amount_with_tax = self.compute( self.amount_untaxed, tax.rate, )

functional core, imperative shell (Gary Bernhardt)

50 / 52

thanks!

51 / 52

thanks!

OCA sponsors

52 / 52


Recommended