├── ConfigurePlot.prj
├── LICENSE
├── README.md
├── finance-conference-signature.png
├── robust2018.prj
├── runTestsWithCobeturaCodeCoverage.m
├── tbx
├── apps
│ ├── ConfigurePlot.mlappinstall
│ ├── ConfigurePlotAppExample.mlapp
│ └── ConfigurePlotAppScreenshot.png
├── demos.xml
├── doc
│ ├── GettingStarted.mlx
│ └── GettingStarted.pdf
├── info.xml
└── robust2018
│ ├── BankAccount.m
│ ├── Contents.m
│ ├── CreateMockObjectExample.mlx
│ ├── DataService.m
│ ├── PropertyValidation.mlx
│ ├── ValidateProps.m
│ ├── findArea.mlx
│ ├── functionSignatures.json
│ ├── html
│ ├── CreateMockObjectExample.html
│ ├── PropertyValidation.html
│ ├── findArea.html
│ └── helptoc.xml
│ ├── mySafeFileTxtWriter.m
│ ├── myUnsafeFileWriter.m
│ └── trader.m
└── test
├── TraderTest.m
├── tBankAccount.m
├── testConfigurePlotAppExample.m
└── testFindArea.m
/ConfigurePlot.prj:
--------------------------------------------------------------------------------
1 |
2 |
3 | ConfigurePlot
4 | Paul Peeling
5 | paul.peeling@mathworks.co.uk
6 | MathWorks
7 |
8 |
9 | Configure a MATLAB Plot
10 |
11 | ${PROJECT_ROOT}\tbx\apps\ConfigurePlotAppScreenshot.png
12 | 1.0
13 |
14 | MATLAB
15 |
16 |
17 | 1
18 |
19 |
20 | 9.4
21 |
22 |
23 | ${PROJECT_ROOT}\tbx\apps
24 | a4d5955f-6c8c-4f2f-8ff4-8c8a04d6a597
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | ${PROJECT_ROOT}\tbx\apps\ConfigurePlotAppExample.mlapp
37 |
38 |
39 |
40 |
41 |
42 | C:\Users\ppeeling\git\fin-conf-2018\tbx\apps
43 |
44 |
45 |
46 | C:\Program Files\MATLAB\R2018a
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | true
58 |
59 |
60 |
61 |
62 | true
63 |
64 |
65 |
66 |
67 | true
68 |
69 |
70 |
71 |
72 | true
73 |
74 |
75 |
76 |
77 | true
78 |
79 |
80 |
81 |
82 | true
83 |
84 |
85 |
86 |
87 | false
88 | false
89 | true
90 | false
91 | false
92 | false
93 | false
94 | false
95 | 10.0
96 | false
97 | true
98 | win64
99 | true
100 |
101 |
102 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018, The MathWorks, Inc.
2 | All rights reserved.
3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
5 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
6 | 3. In all cases, the software is, and all modifications and derivatives of the software shall be, licensed to you solely for use in conjunction with MathWorks products and service offerings.
7 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Developing Robust MATLAB Code
2 | Paul Peeling, Mathworks
3 |
4 | As the size and complexity of your MATLAB® application increases, you want make sure to structure software projects well, ensuring users can run code without encountering unexpected behaviour or errors, for example. In this talk, you will learn about relevant advanced MATLAB software development capabilities, including error handling, object-oriented programming (OOP), unit testing, version control, and change tracking.
5 |
6 | This repository provides the code and examples used in the session.
7 |
8 | Code coverage report for this repository can be generated by the [codecov.io](https://codecov.io) service as described in a recent Developer Zone blog post: [Cov’ed Code All Throughout the Interwebs](https://blogs.mathworks.com/developer/2018/04/17/codecov-and-cobertura/)
9 |
10 | To generate code coverage, run the script
11 | ```
12 | runTestsWithCobeturaCodeCoverage.m
13 | ```
14 |
--------------------------------------------------------------------------------
/finance-conference-signature.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathworks/robust-matlab-2018/1b7844d8dc9d4f3e5cbfc8a14be1dcc2af0ec160/finance-conference-signature.png
--------------------------------------------------------------------------------
/robust2018.prj:
--------------------------------------------------------------------------------
1 |
2 |
3 | robust2018
4 | Paul Peeling
5 | ppeeling@mathworks.com
6 | MathWorks Inc.
7 | Code and Examples from "Developing Robust MATLAB Code"
8 | Code and examples accompanying the session "Developing Robust MATLAB Code" at the MATLAB Computational Finance Conference 2018
9 | ${PROJECT_ROOT}\finance-conference-signature.png
10 | 1.1
11 | ${PROJECT_ROOT}\robust2018.mltbx
12 |
13 | MATLAB
14 |
15 |
16 | 1
17 |
18 |
19 | 9.6
20 |
21 |
22 | 0b8e6fb3-8c8e-4d92-b4a0-27e66c584354
23 |
24 | true
25 | <?xml version="1.0" encoding="utf-8"?>
26 | <examples>
27 | <exampleCategory name="robust2018">
28 | <example name="CreateMockObjectExample" type="html">
29 | <file type="source">/robust2018/html/CreateMockObjectExample.html</file>
30 | <file type="main">/robust2018/CreateMockObjectExample.mlx</file>
31 | <file type="thumbnail"/>
32 | </example>
33 | <example name="PropertyValidation" type="html">
34 | <file type="source">/robust2018/html/PropertyValidation.html</file>
35 | <file type="main">/robust2018/PropertyValidation.mlx</file>
36 | <file type="thumbnail"/>
37 | </example>
38 | <example name="findArea" type="html">
39 | <file type="source">/robust2018/html/findArea.html</file>
40 | <file type="main">/robust2018/findArea.mlx</file>
41 | <file type="thumbnail"/>
42 | </example>
43 | </exampleCategory>
44 | </examples>
45 |
46 |
47 | ${PROJECT_ROOT}\tbx\apps\ConfigurePlot.mlappinstall
48 |
49 |
50 | ${PROJECT_ROOT}\tbx\info.xml
51 | ${PROJECT_ROOT}\tbx\doc\GettingStarted.mlx
52 |
53 |
54 | true
55 |
56 |
57 |
58 | R2018a
59 | latest
60 | false
61 | true
62 | true
63 | true
64 | true
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | ${PROJECT_ROOT}\tbx
100 |
101 |
102 | ${PROJECT_ROOT}\tbx\apps
103 | ${PROJECT_ROOT}\tbx\demos.xml
104 | ${PROJECT_ROOT}\tbx\doc
105 | ${PROJECT_ROOT}\tbx\info.xml
106 | ${PROJECT_ROOT}\tbx\robust2018
107 |
108 |
109 |
110 |
111 |
112 | C:\Users\ppeeling\robust-matlab-2018\robust2018.mltbx
113 |
114 |
115 |
116 | C:\Program Files\MATLAB\R2019a
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 | true
128 |
129 |
130 |
131 |
132 | true
133 |
134 |
135 |
136 |
137 | true
138 |
139 |
140 |
141 |
142 | true
143 |
144 |
145 |
146 |
147 | true
148 |
149 |
150 |
151 |
152 | true
153 |
154 |
155 |
156 |
157 | false
158 | false
159 | true
160 | false
161 | false
162 | false
163 | false
164 | false
165 | 10.0
166 | false
167 | true
168 | win64
169 | true
170 |
171 |
172 |
--------------------------------------------------------------------------------
/runTestsWithCobeturaCodeCoverage.m:
--------------------------------------------------------------------------------
1 | %% Run tests and collect coverage information
2 |
3 | import matlab.unittest.TestRunner
4 | import matlab.unittest.TestSuite
5 | import matlab.unittest.plugins.CodeCoveragePlugin
6 | import matlab.unittest.plugins.codecoverage.CoberturaFormat
7 |
8 | % Define test suite
9 | suite = TestSuite.fromFolder( 'test' );
10 |
11 | % Create and configure the runner
12 | runner = TestRunner.withTextOutput('Verbosity',3);
13 | src = fullfile(pwd,'tbx','robust2018');
14 | coverageFile = fullfile(pwd, 'coverage.xml');
15 | runner.addPlugin(CodeCoveragePlugin.forFolder(src,...
16 | 'Producing', CoberturaFormat(coverageFile)));
17 |
18 | results = runner.run(suite)
19 |
20 | %%
21 | token = '8d46bba7-22e7-4ce1-9dc5-02a052fd6b8e';
22 | setenv( 'CODECOV_TOKEN', token );
23 |
24 | !C:\PROGRA~1\Git\mingw64\bin\curl.exe -s https://codecov.io/bash | C:\PROGRA~1\Git\bin\bash.exe -s || - echo "Codecov did not collect coverage reports"
25 | web( 'https://codecov.io/gh/mathworks/robust-matlab-2018/' )
--------------------------------------------------------------------------------
/tbx/apps/ConfigurePlot.mlappinstall:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathworks/robust-matlab-2018/1b7844d8dc9d4f3e5cbfc8a14be1dcc2af0ec160/tbx/apps/ConfigurePlot.mlappinstall
--------------------------------------------------------------------------------
/tbx/apps/ConfigurePlotAppExample.mlapp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathworks/robust-matlab-2018/1b7844d8dc9d4f3e5cbfc8a14be1dcc2af0ec160/tbx/apps/ConfigurePlotAppExample.mlapp
--------------------------------------------------------------------------------
/tbx/apps/ConfigurePlotAppScreenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathworks/robust-matlab-2018/1b7844d8dc9d4f3e5cbfc8a14be1dcc2af0ec160/tbx/apps/ConfigurePlotAppScreenshot.png
--------------------------------------------------------------------------------
/tbx/demos.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | robust2018
4 | toolbox
5 | HelpIcon.DEMOS
6 |
7 | Code and examples accompanying the session "Developing Robust MATLAB Code" at the MATLAB Computational Finance Conference 2018
8 |
9 |
10 |
11 |
12 | other
13 | CreateMockObjectExample
14 | robust2018/html/CreateMockObjectExample.html
15 |
16 |
17 |
18 | other
19 | PropertyValidation
20 | robust2018/html/PropertyValidation.html
21 |
22 |
23 |
24 | other
25 | findArea
26 | robust2018/html/findArea.html
27 |
28 |
29 |
--------------------------------------------------------------------------------
/tbx/doc/GettingStarted.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathworks/robust-matlab-2018/1b7844d8dc9d4f3e5cbfc8a14be1dcc2af0ec160/tbx/doc/GettingStarted.mlx
--------------------------------------------------------------------------------
/tbx/doc/GettingStarted.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathworks/robust-matlab-2018/1b7844d8dc9d4f3e5cbfc8a14be1dcc2af0ec160/tbx/doc/GettingStarted.pdf
--------------------------------------------------------------------------------
/tbx/info.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2018a
4 | robust2018
5 | toolbox
6 |
7 | robust2018\html
8 |
9 |
--------------------------------------------------------------------------------
/tbx/robust2018/BankAccount.m:
--------------------------------------------------------------------------------
1 | classdef BankAccount
2 |
3 | properties
4 | AccountNumber
5 | AccountBalance
6 | AccountStatus
7 | end
8 |
9 | methods
10 |
11 | function ba = BankAccount(accountNumber, accountBalance)
12 | ba.AccountNumber = accountNumber;
13 | ba.AccountBalance = accountBalance;
14 | ba.AccountStatus = 'Open';
15 | end
16 |
17 | function ba = deposit(ba, amount)
18 | validateattributes(amount, {'double'}, {'scalar', 'positive'});
19 | ba.AccountBalance = ba.AccountBalance + amount;
20 | end
21 |
22 | function ba = withdraw(ba, amount)
23 | ba.AccountBalance = ba.AccountBalance - amount;
24 | if ba.AccountBalance < 0
25 | ba.AccountStatus = 'Overdraft';
26 | end
27 | end
28 |
29 | end
30 | end
--------------------------------------------------------------------------------
/tbx/robust2018/Contents.m:
--------------------------------------------------------------------------------
1 | % ROBUST2018
2 | % Version 1.0 24-May-2018
3 | %
4 | % Files
5 | % DataService - a data service to retrieve the stock price data
6 | % mySafeFileTxtWriter - mySafeFileTxtWriter writes data to a text file and cleans up
7 | % myUnsafeFileWriter - myUnsafeFileWriter writes data to a file without cleaning up
8 | % trader - an algorithm for buying stock
9 | % ValidateProps - The ValidateProps class defines three properties with validation
10 | % findArea - returns the area of shape with given dimensions
11 | % CreateMockObjectExample - test an algorithm for buying stock, but do not test the entire system
12 | % PropertyValidation - example showing validation on property values
13 | %
14 | % Copyright 2018 MathWorks Inc.
15 |
--------------------------------------------------------------------------------
/tbx/robust2018/CreateMockObjectExample.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathworks/robust-matlab-2018/1b7844d8dc9d4f3e5cbfc8a14be1dcc2af0ec160/tbx/robust2018/CreateMockObjectExample.mlx
--------------------------------------------------------------------------------
/tbx/robust2018/DataService.m:
--------------------------------------------------------------------------------
1 | classdef DataService
2 | % a data service to retrieve the stock price data
3 |
4 | % Copyright 2018 MathWorks Inc.
5 | methods (Abstract,Static)
6 | price = lookupPrice(ticker,date)
7 | end
8 | end
--------------------------------------------------------------------------------
/tbx/robust2018/PropertyValidation.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathworks/robust-matlab-2018/1b7844d8dc9d4f3e5cbfc8a14be1dcc2af0ec160/tbx/robust2018/PropertyValidation.mlx
--------------------------------------------------------------------------------
/tbx/robust2018/ValidateProps.m:
--------------------------------------------------------------------------------
1 | classdef ValidateProps
2 | % The ValidateProps class defines three properties with validation
3 |
4 | % Copyright 2018 MathWorks Inc.
5 | properties
6 | Location(1,3) double {mustBeReal, mustBeFinite}
7 | Label(1,:) char {mustBeMember(Label,{'High','Medium','Low'})} = 'Low'
8 | State(1,1) matlab.lang.OnOffSwitchState
9 | end
10 | end
--------------------------------------------------------------------------------
/tbx/robust2018/findArea.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mathworks/robust-matlab-2018/1b7844d8dc9d4f3e5cbfc8a14be1dcc2af0ec160/tbx/robust2018/findArea.mlx
--------------------------------------------------------------------------------
/tbx/robust2018/functionSignatures.json:
--------------------------------------------------------------------------------
1 | {
2 | "_schemaVersion": "1.0.0",
3 | "findArea": {
4 | "inputs": [
5 | {
6 | "name": "shape",
7 | "kind": "required",
8 | "type": [
9 | "char",
10 | "choices={'circle','rectangle'}"
11 | ],
12 | "purpose": "shape"
13 | },
14 | {
15 | "name": "dim1",
16 | "kind": "required",
17 | "type": [
18 | "numeric"
19 | ],
20 | "purpose": "1st dimension"
21 | },
22 | {
23 | "name": "dim2",
24 | "kind": "ordered",
25 | "type": [
26 | "numeric"
27 | ],
28 | "purpose": "2nd dimension"
29 | }
30 | ]
31 | }
32 | }
--------------------------------------------------------------------------------
/tbx/robust2018/html/CreateMockObjectExample.html:
--------------------------------------------------------------------------------
1 |
2 |
Mocking Framework
Mocking Framework
Create mocks for the depended-on components.
Define behaviors of the mocks.
Test the component of interest.
Qualify interactions between the component of interest and the mocked components.
Stubbing - define behaviour
Spying - intercept and remember
Create a mock test case for interactive use.
import matlab.mock.TestCase
testCase = TestCase.forInteractiveUse
testCase =
InteractiveTestCase with no properties.
36 |
Depended on Components
The day-trading algorithm has two dependencies: a data service to retrieve the stock price data and a broker to purchase the stock.
type DataService.m
classdef DataService
37 | % a data service to retrieve the stock price data
38 |
39 | % Copyright 2018 MathWorks Inc.
40 | methods (Abstract,Static)
41 | price = lookupPrice(ticker,date)
42 | end
43 | end
In production code, there could be several concrete implementations of the DataService class, such as aBloombergDataService class.
Create Stub to Define Behavior
Create a mock for the data service dependency. The data service mock returns predefined values.
Verify thatFOO stock was purchased two times, regardless of the specified number of shares. While theverifyCalled method is convenient to specify behavior, there is more functionality if you use theWasCalled constraint. For example, you can verify that a mocked method was called a specified number of times.
Although thetrader function was called requesting 100 shares ofBAR stock, the stub defined yesterday's price forBAR to return a higher value than all days prior to yesterday. Therefore, the broker never buys stock"BAR".
Copyright 2018 MathWorks Inc.
54 |
55 |
--------------------------------------------------------------------------------
/tbx/robust2018/html/PropertyValidation.html:
--------------------------------------------------------------------------------
1 |
2 | Sample Class Using Property Validation
Sample Class Using Property Validation
The ValidateProps class defines three properties with validation.
Initializes theLocationproperty value to[0 0 0]to satisfy the size and class requirements.
Sets theLabelproperty to its default value,'Low'. The default value must be a member of the allowed set of values. The emptycharimplicit default value would cause an error.
Sets theStateproperty to theoffenumeration member defined by the matlab.lang.OnOffSwitchState class.