Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
TDD & VIPER
1. TDD & VIPER
Made For Each Other
Presented by Lyle Resnick
lyle@cellarpoint.com
2. Rules of Thumb
• Test either the output or the side effects but not
both at the same time
• Output is captured either by result or protocol
• Side effects are captured by properties of
overridden methods
9. Start With The View
• Its comfortable
• Start with the IB Injection Tests
• Create Views for all states
10. Create Views For All States
• For One Event
• Not just the happy path
• Nothing, Loading, None, One, Some, Too Many,
Correct, Done
• Incorrect
• Semantic or Systemic Error
12. IB Injection Tests
• Instantiate the ViewController as the SUT
• Repeat This:
• Create a Failing Test
• Layout the Views in IB
• associate with classes and identifiers
• Create and Connect Outlets
• Pass the Test
13. ViewController Tests
• Start with PresenterOutput
• Called by the Presenter
• Instantiate ViewController as the SUT via FakeIBLoader
• Loader sets the views into the cell outlets
• Repeat This:
• Create a Failing Test
• Implement the UseCaseOutput method of interest
• Capture behaviour via View properties or adapter Mocks/Stubs
• Verify and pass the Test
14. Cell Tests
• Populate the Cells
• Repeat This:
• Create a Failing Test
• instantiate a cell
• set the views into the cell outlets
• Add the cell Protocol to the cell and implement the show method
• Call the show method on the cell
• Get the set values
• Verify and pass the Test
15. Presenter Tests
• Start with UseCaseOutput
• Called by the UseCase (or the Transformer)
• Instantiate Presenter as the SUT
• Repeat This:
• Create a Failing Test
• Implement the UseCaseOutput method of interest
• Capture behaviour via ViewController Mocks/Stub
• Verify and pass the Test
16. View Model Tests
• Create the ViewModels for Cells
• Instantiate Presenter as the SUT
• Implement the presenter’s ViewModel collection and public accessors
• Repeat This:
• Create a Failing Test by calling present method
• implement the present method
• Call the UseCaseOutput present method on the Presenter
• Get the set values on the ViewModels
• Verify and pass the Test
17. Table Adapter Tests
• Test the ViewModel access
• Called by the TableView
• Instantiate the TableAdapter as the SUT
• Configure the Presenter
• Repeat This:
• Create a Failing Test
• Call the UITableViewDataSource/Delegate method
• Implement the UITableViewDataSource/Delegate method
• Capture output via calls to SUT
• Verify and pass the Test
18. Transformer Tests
• This is where the action happens
• Allows test of pure algorithm with no conversions
• Instantiate the Transformer as the SUT
• Create Fake Models to stand-in for output
• Implement UseCaseOutput with fake models
• Repeat this:
• Create data sets for cases
• run the transform method
• Verify and pass the Test
19. The Rest of the Tests
• Test the events from
• the ViewController to the Presenter
• the Presenter to the UseCase
• the UseCase to the Transformer
• the Transformer back to the Presenter
Editor's Notes
clone or download the code at:
https://github.com/lyleresnick/CleanTDDReportTableDemo
if there is a result, test that
if not test the behaviour
Seams provide a natural way to insert tests into the code
Protocols provide a place to send output between stages
The plan is known amongst the team
With TDD creating connector concurrently leads to creation of VIPER classes
View Delegates like TableView datasources and TextEdit delegates
Easier to generate
You can test them all at once
Organize by Event
Use one output protocol per event
The Nine States of Design
https://medium.com/swlh/the-nine-states-of-design-5bfe9b3d6d85
Injection Tests
https://github.com/lyleresnick/CleanTDDReportTableDemo/blob/master/CleanTDDReportTableDemo/Scenes/AccountDetailsTransactionList/View/TransactionListViewControllerIBInjectionTests.swift
This is a normal whether you are doing VIPER or not
ViewController
https://github.com/lyleresnick/CleanTDDReportTableDemo/blob/master/CleanTDDReportTableDemo/Scenes/AccountDetailsTransactionList/View/TransactionListViewController.swift
Code - showReport()
https://github.com/lyleresnick/CleanTDDReportTableDemo/blob/master/CleanTDDReportTableDemo/Scenes/AccountDetailsTransactionList/View/TransactionListViewControllerTests.swift
Test - TransactionListViewControllerTests.test_showReport_CallsTableViewGetRowCount
https://github.com/lyleresnick/CleanTDDReportTableDemo/blob/master/CleanTDDReportTableDemo/Scenes/AccountDetailsTransactionList/View/TransactionListViewController.swift
with respect to adapter
depending on what you implement first, you may have to implement stubs for the first time and change the code to override later
public accessors = rowCount() and row(at:)
Code - presentHeader()
https://github.com/lyleresnick/CleanTDDReportTableDemo/blob/master/CleanTDDReportTableDemo/Scenes/AccountDetailsTransactionList/Presenter/TransactionListViewModel.swift
https://github.com/lyleresnick/CleanTDDReportTableDemo/blob/master/CleanTDDReportTableDemo/Scenes/AccountDetailsTransactionList/Presenter/TransactionListPresenter.swift
Tests - TransactionListViewModelTests.test_presentHeader_AppendsHeader()
https://github.com/lyleresnick/CleanTDDReportTableDemo/blob/master/CleanTDDReportTableDemo/Scenes/AccountDetailsTransactionList/Presenter/TransactionListViewModelTests.swift
you will have to change previous stubs to overrides once implemented
Code
https://github.com/lyleresnick/CleanTDDReportTableDemo/blob/master/CleanTDDReportTableDemo/Scenes/AccountDetailsTransactionList/View/TransactionListAdapter.swift
Tests - TransactionListAdapterTests.test_NumberOfRowsInSection_ReturnsRowCountOfPresenter()
https://github.com/lyleresnick/CleanTDDReportTableDemo/blob/master/CleanTDDReportTableDemo/Scenes/AccountDetailsTransactionList/View/TransactionListAdapterTests.swift
UseCase Tests for connecting output to Transformer
TransactionListUseCaseTwoSourceTests.test_beginTwoSource_CallsTransformerWithPresenter()
UseCase Tests for connecting input to Transformer
TransactionListUseCaseTwoSourceTests.test_beginTwoSource_CallsTransformer()
Configurator tests to test show is being called
TransactionViewListCellConfiguratorTests.test_Show_CallsCellsShowWithRow()
Presenter Tests for events to Use Case
TransactionListPresenterTests.test_eventViewReady_CallsUseCase_beginTwoSource()
ViewController Tests for Events to presenter
TransactionListViewControllerTests.test_viewDidLoad_CallsPresenterEventViewReady