SlideShare a Scribd company logo
How Test Newbie began testing
01 Story about how I did
REAL Benefits I felt while doing TLD & TDD
▪ TLD (Test Last Development)
▪ TDD (Test Driven Development)
CONTENTS
02
In this presentation, “Test” means unit test only.
The language is JavaScript.
The test framework is Jest.
There's a React code, but it doesn't matter if you don't know it.
NOTICE
Story about.
How I did.
1-1
What is the TDD and TLD?
Red Green
Refactor
(Fail) (Success)
(Success)
Red Green
Refactor
(Fail) (Success)
(Success)
Write the functional code until the test passes.
Red Green
Refactor
(Fail) (Success)
(Success) Refactor both new and old code
to make it well structured.
Red Green
Refactor
(Fail) (Success)
(Success)
Red Green
Refactor
(Fail) (Success)
(Success)
TDD – Test Driven Development
TDD TLD
Red Green
Refactor
(Fail) (Success)
(Success)
No
code
Red Green
Refactor
(Fail) (Success)
(Success)
Wrong
code
TDD
Red Green
Refactor
(Fail) (Success)
(Success)
No
code
The Red step in TDD means that
there is no implementation code.
This means that it hasn’t been
implemented yet.
TLD
Red Green
Refactor
(Fail) (Success)
(Success)
Wrong
code
The Red step in TLD means that
there is(are) a bug(s).
This means that there is a wrong code.
1-2
* TLD
Adding tests to legacy code
Code easy
to test
Code hard
to test
Production code
Pure function
External Dependency
Start with code that's already made easy to test
ex. utility, helper
// YY. M. DD.-> YYMMDD
export function formatDateForQueryString(dateString) {
const splitArray = dateString.split('.’);
splitArray.map((el, i, arr) => {
arr[i] = el.replace(/ /gi, '').length === 1 ? '0' + el : el;
});
return result.join('').replace(/ /gi, '');
}
Code easy
to test
Function that converts a string in format 'YY. M. DD. ' to a string in format 'YYMMDD'
// dateHelper.test.js
describe('formatDateForQueryString function', () => {
describe(‘converts a string in format “YY. M. DD.”', () => {
test(‘to a string in “YYMMDD”.', () => {
const actual = formatDateForQueryString('18. 1. 10.');
expect(actual).toBe('180110');
});
});
});
Don’t change production codes
// YY. M. DD.-> YYMMDD
export function formatDateForQueryString(dateString) {
const splitArray = dateString.split('.’);
splitArray.map((el, i, arr) => {
arr[i] = el.replace(/ /gi, '').length === 1 ? '0' + el : el;
});
return result.join('').replace(/ /gi, '');
}
Code easy
to test
// dateHelper.test.js
describe('formatDateForQueryString function', () => {
describe(‘converts a string in format “YY. M. DD.”', () => {
test(‘to a string in “YYMMDD”.', () => {
const actual = formatDateForQueryString('18. 1. 10.');
expect(actual).toBe('180110');
});
});
}); Don’t change the test codes
Function that converts a string in format 'YY. M. DD. ' to a string in format 'YYMMDD'
// YY. M. DD.-> YYMMDD
export function formatDateForQueryString(dateString) {
const splitArray = dateString.split('.’);
splitArray.map((el, i, arr) => {
arr[i] = el.replace(/ /gi, '').length === 1 ? '0' + el : el;
});
return result.join('').replace(/ /gi, '');
}
Code easy
to test
export function formatDateForQueryString(dateString) {
return `${dateString} `
.split('. ')
.map(x => (x.length === 1 ? `0${x}` : x))
.join('');
}
The refactoring should be limited to the extent that the test is not broken.
Refactor
Ex. Maybe almost?
Separate only those codes that are easy to test from those that are made difficult to test.
Code easy
to test
Code hard
to test
Production code
Parts include high-value business logic
Buggy code (current, not past)
Low coupling and complex logic*
Where can I find it?
*Low or no external dependency (independent environment)
and business logic is complex (Replace username to email, etc.)
Code hard
to test
easy
hard
easy
Overall flow
Find the testable code, Separate them, Add test code, And Refactor
Refactor
Red
Green
or
class RegistrationFormContainer extends Component {
/ * (Omitted) Methods on modal behavior * /
handleSubmit = async () => {
const { validValues } = this.props.form;
const phone = validValues.phone
? '+82' + validValues.phone.slice(1)
: null;
const command = {
username: validValues.username || validValues.email,
email: validValues.email,
phone: phone,
};
try {
await postRegisterRequest(command);
this.closeModal();
} catch (err) {
Modal.error({ /* ... */ });
}
};
render() { /* ... */ }
}
}
Code hard
to test
* React code
This contains important business logic.
Why this code is difficult to test
• API request
• Different UI depending on the result of the response
Only separate testable parts
 API request
function formatRegisterCommand() {
const { validValues } = this.props.form;
const phone = validValues.phone
? '+82' + validValues.phone.slice(1)
: null;
const command = {
username:
validValues.username || validValues.email,
email: validValues.email,
phone: phone,
};
return command;
}
export default formatRegisterCommand;
import formatRegisterCommand /* ... */
describe('formatRegisterCommand function ', () => {
test(‘does not throw error.', () => {
expect(formatRegisterCommand).not.toThrowError();
});
});
UTF-8 LF JavaScript React Prettier:
formatRegisterCommand.js formatRegisterCommand.test.js
function formatRegisterCommand() {
const { validValues } = this.props.form;
const phone = validValues.phone
? '+82' + validValues.phone.slice(1)
: null;
const command = {
username:
validValues.username || validValues.email,
email: validValues.email,
phone: phone,
};
return command;
}
export default formatRegisterCommand;
import formatRegisterCommand /* ... */
describe('formatRegisterCommand function ', () => {
test(‘does not throw error.', () => {
expect(formatRegisterCommand).not.toThrowError();
});
});
UTF-8 LF JavaScript React Prettier:
formatRegisterCommand.js formatRegisterCommand.test.js
Removes framework-dependent (=external dependency) code
function formatRegisterCommand(validValues={}){
const phone = validValues.phone
? '+82' + validValues.phone.slice(1)
: null;
const command = {
username:
validValues.username || validValues.email,
email: validValues.email,
phone: phone,
};
return command;
}
export default formatRegisterCommand;
import formatRegisterCommand /* ... */
describe('formatRegisterCommand function ', () => {
test(‘does not throw error.', () => {
expect(formatRegisterCommand).not.toThrowError();
});
});
UTF-8 LF JavaScript React Prettier:
formatRegisterCommand.js formatRegisterCommand.test.js
Make it an independent function that is not affected externally
function formatRegisterCommand(validValues={}){
const phone = validValues.phone
? '+82' + validValues.phone.slice(1)
: null;
const command = {
username:
validValues.username || validValues.email,
email: validValues.email,
phone: phone,
};
return command;
}
export default formatRegisterCommand;
/* ... */
describe('returns a command', () => {
const param = {
username: 'user',
email: 'user@email.com',
phone: '01012345678',
agreement: [true, true, true],
};
describe('whose username property should be', () => {
test('the same as the username of the argument.’, () => {
const actual = formatRegisterCommand(param);
expect(actual.username).toBe(param.username);
});
});
});
UTF-8 LF JavaScript React Prettier:
formatRegisterCommand.js formatRegisterCommand.test.js
Add a spec about the return value
Develop new code with TDD.
1-3
I received additional business requirements.
"A user must agree all the terms to sign up."
/* ... */
describe('whose agreement property should be', () => {
test('return false when any of the arguments are false',()=> {
const actual = formatRegisterCommand({
...param,
agreement: [true, true, false],
});
expect(actual).toBe(false);
});
});
/* ... */
UTF-8 LF JavaScript React Prettier:
formatRegisterCommand.js formatRegisterCommand.test.js
function formatRegisterCommand(source = {}) {
const { username, email, phone } = source;
return {
username: username || email,
email,
phone: phone ? `+82${phone.slice(1)}` : null,
};
}
export default formatRegisterCommand;
/* ... */
describe('whose agreement property should be', () => {
test('return false when any of the arguments are false',()=> {
const actual = formatRegisterCommand({
...param,
agreement: [true, true, false],
});
expect(actual).toBe(false);
});
});
/* ... */
UTF-8 LF JavaScript React Prettier:
formatRegisterCommand.js formatRegisterCommand.test.js
function formatRegisterCommand(source = {}) {
const { username, email, phone } = source;
if (source.agreement.some(agree => !agree)) {
return false;
}
return {
username: username || email,
email,
phone: phone ? `+82${phone.slice(1)}` : null,
};
}
export default formatRegisterCommand;
if (source.agreement.some(agree => !agree)) {
return false;
}
Summarize
1-4
1. Adding tests to legacy code (+Refactor)
2. Develop new code with TDD.
HOW: Follows below cycle
Separate
as function
Refactor
Add test
code
WHAT: Codes easy to test
- Parts includes high-value business logic
- The spot where the bug was found (formerly X)
- Low coupling and complex logic
TLD
1. Add tests to code that is already easy to test.
2. Make your code easy to test, and then test.
TDD
- Where to add new features
REAL Benefits.
I felt while doing TLD & TDD.
Less anxious, Less stress
Things I really felt while doing TEST.
/* ... */
describe('formatRegisterCommand function', () => {
test(‘does not throw error.', () => {
expect(formatRegisterCommand).not.toThrowError();
});
});
describe(‘whose agreement property should be', () => {
test('return false when any of the arguments are fal
=> {
const actual = formatRegisterCommand({
...param,
agreement: [true, true, false],
});
expect(actual).toBe(false);
});
});
/* ... */
UTF-8 LF JavaScript React Prettier:
formatRegisterCommand.js formatRegisterCommand.test.js
function formatRegisterCommand(source = {}) {
const { username, email, phone } = source;
if (source.agreement.some(agree => !agree)) {
return false;
}
return {
username: username || email,
email,
phone: phone ? `+82${phone.slice(1)}` : null,
};
}
export default formatRegisterCommand;
if (source.agreement.some(agree => !agree)) {
return false;
}
FAIL src/business/formatRegisterCommand.test.js
● formatRegisterCommand function › does not throw error.
expect(function).not.toThrowError()
Expected the function not to throw an error.
Instead, it threw:
TypeError: Cannot read property 'some' of undefined
at formatRegisterCommand (src/business/formatRegisterCommand.js:9:17)
/* ... */
formatRegisterCommand function
✓ does not throw error.
return command
UTF-8 LF JavaScript React Prettier:
The test code makes me to find the
code smell pretty often.
Things I really felt while doing TEST.
Improve the design of code
PASS src/business/formatRegisterCommand.test.js
formatRegisterCommand function
✓ does not throw error.
return command
whose username property should be
✓ equal to username value of argument.
✓ equal to email value of argument when username value is falsy value.
whose email property should be
✓ equal to email value of argument.
whose phone property should be
✓ the value of phone property of argument that changed the first 0 to ..
whose agreement property should be
✓ return false when any of the arguments are false.
For example,
PASS src/business/formatRegisterCommand.test.js
formatRegisterCommand function
✓ does not throw error.
return command
whose username property should be
✓ equal to username value of argument.
✓ equal to email value of argument when username value is falsy value.
whose email property should be
✓ equal to email value of argument.
whose phone property should be
✓ the value of phone property of argument that changed the first 0 to ..
whose agreement property should be
✓ return false when any of the arguments are false.
For example,
2 Type of return value.
- command object
- false
2 Responsibilities.
- Decide whether user can join
- Format input values to command object
formatRegisterCommand.js
function formatRegisterCommand(source = {}) {
const { username, email, phone } = source;
const agreement = source.agreement || [];
if (agreement.some(agree => !agree))
return false;
return {
username: username || email,
email,
phone: phone
? `+82${phone.slice(1)}`
: null,
};
}
export default formatRegisterCommand;
UTF-8 LF JavaScript React Prettier:
I realize how bad design skills I have.
So I'm interested in stable code and good design.
Motivation for learning
Things I really felt while doing TEST & TDD.
Bug tracking time is significantly reduced.
Improve development productivity
* Time saved without testing ≤ Time to fix a bug from not tested code
* It’s my subjective feeling. No objectivity.
Things I really felt while doing TEST & TDD.
I've found some loopholes in business logic *in advance.
Improve project productivity
*Before I (or we) start coding
Things I really felt while doing TDD.
TDD controls that I don’t do more than one thing at a time.
It makes me focus more on what I have to do right now.
Concentration is improved
Things I really felt while doing TDD.
Original article: https://www.facebook.com/notes/kent-beck/rip-tdd/750840194948847/
RIP TDD: The article criticizes DHH's article, "TDD is dead."
In this article, Kent Beck mentions the benefits of TDD.
-
Over-engineering.
I have a tendency to "throw in" functionality I "know" I'm
"going to need". Making one red test green (along with the
list of future tests) helps me implement just enough. I need
to find a new way to stay focused.
THANK YOU

More Related Content

What's hot

Clean code
Clean codeClean code
Clean code
Arturo Herrero
 
Clean code
Clean codeClean code
Clean code
Henrique Smoco
 
What’s new in .NET
What’s new in .NETWhat’s new in .NET
What’s new in .NET
Doommaker
 
The Ring programming language version 1.9 book - Part 47 of 210
The Ring programming language version 1.9 book - Part 47 of 210The Ring programming language version 1.9 book - Part 47 of 210
The Ring programming language version 1.9 book - Part 47 of 210
Mahmoud Samir Fayed
 
2.overview of c#
2.overview of c#2.overview of c#
2.overview of c#Raghu nath
 
2 introduction toentitybeans
2 introduction toentitybeans2 introduction toentitybeans
2 introduction toentitybeans
ashishkirpan
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
Geshan Manandhar
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
Mario Sangiorgio
 
IP project for class 12 cbse
IP project for class 12 cbseIP project for class 12 cbse
IP project for class 12 cbse
siddharthjha34
 
Clean code
Clean codeClean code
Clean code
ifnu bima
 
The Ring programming language version 1.8 book - Part 44 of 202
The Ring programming language version 1.8 book - Part 44 of 202The Ring programming language version 1.8 book - Part 44 of 202
The Ring programming language version 1.8 book - Part 44 of 202
Mahmoud Samir Fayed
 
Reanalyzing the Notepad++ project
Reanalyzing the Notepad++ projectReanalyzing the Notepad++ project
Reanalyzing the Notepad++ project
PVS-Studio
 
Functional Programming in C#
Functional Programming in C#Functional Programming in C#
Functional Programming in C#
Giorgio Zoppi
 
Refactoring group 1 - chapter 3,4,6
Refactoring   group 1 - chapter 3,4,6Refactoring   group 1 - chapter 3,4,6
Refactoring group 1 - chapter 3,4,6Duy Lâm
 
Test and refactoring
Test and refactoringTest and refactoring
Test and refactoring
Kenneth Ceyer
 
Giorgio zoppi cpp11concurrency
Giorgio zoppi cpp11concurrencyGiorgio zoppi cpp11concurrency
Giorgio zoppi cpp11concurrency
Giorgio Zoppi
 
Object Calisthenics em Go
Object Calisthenics em GoObject Calisthenics em Go
Object Calisthenics em Go
Elton Minetto
 
Антихрупкий TypeScript | Odessa Frontend Meetup #17
Антихрупкий TypeScript | Odessa Frontend Meetup #17Антихрупкий TypeScript | Odessa Frontend Meetup #17
Антихрупкий TypeScript | Odessa Frontend Meetup #17
OdessaFrontend
 
POLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAPOLITEKNIK MALAYSIA
POLITEKNIK MALAYSIA
Aiman Hud
 

What's hot (20)

Clean code
Clean codeClean code
Clean code
 
Clean code
Clean codeClean code
Clean code
 
What’s new in .NET
What’s new in .NETWhat’s new in .NET
What’s new in .NET
 
The Ring programming language version 1.9 book - Part 47 of 210
The Ring programming language version 1.9 book - Part 47 of 210The Ring programming language version 1.9 book - Part 47 of 210
The Ring programming language version 1.9 book - Part 47 of 210
 
2.overview of c#
2.overview of c#2.overview of c#
2.overview of c#
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
2 introduction toentitybeans
2 introduction toentitybeans2 introduction toentitybeans
2 introduction toentitybeans
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
 
IP project for class 12 cbse
IP project for class 12 cbseIP project for class 12 cbse
IP project for class 12 cbse
 
Clean code
Clean codeClean code
Clean code
 
The Ring programming language version 1.8 book - Part 44 of 202
The Ring programming language version 1.8 book - Part 44 of 202The Ring programming language version 1.8 book - Part 44 of 202
The Ring programming language version 1.8 book - Part 44 of 202
 
Reanalyzing the Notepad++ project
Reanalyzing the Notepad++ projectReanalyzing the Notepad++ project
Reanalyzing the Notepad++ project
 
Functional Programming in C#
Functional Programming in C#Functional Programming in C#
Functional Programming in C#
 
Refactoring group 1 - chapter 3,4,6
Refactoring   group 1 - chapter 3,4,6Refactoring   group 1 - chapter 3,4,6
Refactoring group 1 - chapter 3,4,6
 
Test and refactoring
Test and refactoringTest and refactoring
Test and refactoring
 
Giorgio zoppi cpp11concurrency
Giorgio zoppi cpp11concurrencyGiorgio zoppi cpp11concurrency
Giorgio zoppi cpp11concurrency
 
Object Calisthenics em Go
Object Calisthenics em GoObject Calisthenics em Go
Object Calisthenics em Go
 
Антихрупкий TypeScript | Odessa Frontend Meetup #17
Антихрупкий TypeScript | Odessa Frontend Meetup #17Антихрупкий TypeScript | Odessa Frontend Meetup #17
Антихрупкий TypeScript | Odessa Frontend Meetup #17
 
POLITEKNIK MALAYSIA
POLITEKNIK MALAYSIAPOLITEKNIK MALAYSIA
POLITEKNIK MALAYSIA
 

Similar to Tdd.eng.ver

Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy codeShriKant Vashishtha
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimizedWoody Pewitt
 
Analysis of Microsoft Code Contracts
Analysis of Microsoft Code ContractsAnalysis of Microsoft Code Contracts
Analysis of Microsoft Code Contracts
PVS-Studio
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorNeeraj Kaushik
 
GDSC Flutter Forward Workshop.pptx
GDSC Flutter Forward Workshop.pptxGDSC Flutter Forward Workshop.pptx
GDSC Flutter Forward Workshop.pptx
GDSCVJTI
 
NDC 2011, C++ 프로그래머를 위한 C#
NDC 2011, C++ 프로그래머를 위한 C#NDC 2011, C++ 프로그래머를 위한 C#
NDC 2011, C++ 프로그래머를 위한 C#
tcaesvk
 
Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]
JavaScript Meetup HCMC
 
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsTypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
Alfonso Peletier
 
Practical TypeScript
Practical TypeScriptPractical TypeScript
Practical TypeScript
ldaws
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
Christoffer Noring
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4Abed Bukhari
 
Introduction to AJAX and DWR
Introduction to AJAX and DWRIntroduction to AJAX and DWR
Introduction to AJAX and DWR
SweNz FixEd
 
Unit Testing Front End JavaScript
Unit Testing Front End JavaScriptUnit Testing Front End JavaScript
Unit Testing Front End JavaScript
FITC
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
R696
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
Danylenko Max
 
WD programs descriptions.docx
WD programs descriptions.docxWD programs descriptions.docx
WD programs descriptions.docx
anjani pavan kumar
 
Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17
LogeekNightUkraine
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
Uldis Sturms
 
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
priestmanmable
 

Similar to Tdd.eng.ver (20)

Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
 
Analysis of Microsoft Code Contracts
Analysis of Microsoft Code ContractsAnalysis of Microsoft Code Contracts
Analysis of Microsoft Code Contracts
 
C-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression CalculatorC-Sharp Arithmatic Expression Calculator
C-Sharp Arithmatic Expression Calculator
 
GDSC Flutter Forward Workshop.pptx
GDSC Flutter Forward Workshop.pptxGDSC Flutter Forward Workshop.pptx
GDSC Flutter Forward Workshop.pptx
 
NDC 2011, C++ 프로그래머를 위한 C#
NDC 2011, C++ 프로그래머를 위한 C#NDC 2011, C++ 프로그래머를 위한 C#
NDC 2011, C++ 프로그래머를 위한 C#
 
Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]Writing testable js [by Ted Piotrowski]
Writing testable js [by Ted Piotrowski]
 
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsTypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
 
Practical TypeScript
Practical TypeScriptPractical TypeScript
Practical TypeScript
 
Typescript barcelona
Typescript barcelonaTypescript barcelona
Typescript barcelona
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 
Introduction to AJAX and DWR
Introduction to AJAX and DWRIntroduction to AJAX and DWR
Introduction to AJAX and DWR
 
Unit Testing Front End JavaScript
Unit Testing Front End JavaScriptUnit Testing Front End JavaScript
Unit Testing Front End JavaScript
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
 
WD programs descriptions.docx
WD programs descriptions.docxWD programs descriptions.docx
WD programs descriptions.docx
 
Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17
 
My java file
My java fileMy java file
My java file
 
Redux vs Alt
Redux vs AltRedux vs Alt
Redux vs Alt
 
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
 

More from 혜승 이

2nd. aop
2nd. aop2nd. aop
2nd. aop
혜승 이
 
How to edit my commit
How to edit my commitHow to edit my commit
How to edit my commit
혜승 이
 
About git
About gitAbout git
About git
혜승 이
 
Cgs web project
Cgs web projectCgs web project
Cgs web project
혜승 이
 
밑바닥부터 시작하는 딥러닝 - 학습관련기술들 스크립트
밑바닥부터 시작하는 딥러닝 - 학습관련기술들 스크립트밑바닥부터 시작하는 딥러닝 - 학습관련기술들 스크립트
밑바닥부터 시작하는 딥러닝 - 학습관련기술들 스크립트
혜승 이
 
Ch6.학습관련기술들
Ch6.학습관련기술들Ch6.학습관련기술들
Ch6.학습관련기술들
혜승 이
 

More from 혜승 이 (6)

2nd. aop
2nd. aop2nd. aop
2nd. aop
 
How to edit my commit
How to edit my commitHow to edit my commit
How to edit my commit
 
About git
About gitAbout git
About git
 
Cgs web project
Cgs web projectCgs web project
Cgs web project
 
밑바닥부터 시작하는 딥러닝 - 학습관련기술들 스크립트
밑바닥부터 시작하는 딥러닝 - 학습관련기술들 스크립트밑바닥부터 시작하는 딥러닝 - 학습관련기술들 스크립트
밑바닥부터 시작하는 딥러닝 - 학습관련기술들 스크립트
 
Ch6.학습관련기술들
Ch6.학습관련기술들Ch6.학습관련기술들
Ch6.학습관련기술들
 

Recently uploaded

FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 

Recently uploaded (20)

FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 

Tdd.eng.ver

  • 1. How Test Newbie began testing
  • 2. 01 Story about how I did REAL Benefits I felt while doing TLD & TDD ▪ TLD (Test Last Development) ▪ TDD (Test Driven Development) CONTENTS 02
  • 3. In this presentation, “Test” means unit test only. The language is JavaScript. The test framework is Jest. There's a React code, but it doesn't matter if you don't know it. NOTICE
  • 5. 1-1 What is the TDD and TLD?
  • 7. Red Green Refactor (Fail) (Success) (Success) Write the functional code until the test passes.
  • 8. Red Green Refactor (Fail) (Success) (Success) Refactor both new and old code to make it well structured.
  • 11. TDD TLD Red Green Refactor (Fail) (Success) (Success) No code Red Green Refactor (Fail) (Success) (Success) Wrong code
  • 12. TDD Red Green Refactor (Fail) (Success) (Success) No code The Red step in TDD means that there is no implementation code. This means that it hasn’t been implemented yet.
  • 13. TLD Red Green Refactor (Fail) (Success) (Success) Wrong code The Red step in TLD means that there is(are) a bug(s). This means that there is a wrong code.
  • 14. 1-2 * TLD Adding tests to legacy code
  • 15. Code easy to test Code hard to test Production code Pure function External Dependency Start with code that's already made easy to test ex. utility, helper
  • 16. // YY. M. DD.-> YYMMDD export function formatDateForQueryString(dateString) { const splitArray = dateString.split('.’); splitArray.map((el, i, arr) => { arr[i] = el.replace(/ /gi, '').length === 1 ? '0' + el : el; }); return result.join('').replace(/ /gi, ''); } Code easy to test Function that converts a string in format 'YY. M. DD. ' to a string in format 'YYMMDD' // dateHelper.test.js describe('formatDateForQueryString function', () => { describe(‘converts a string in format “YY. M. DD.”', () => { test(‘to a string in “YYMMDD”.', () => { const actual = formatDateForQueryString('18. 1. 10.'); expect(actual).toBe('180110'); }); }); }); Don’t change production codes
  • 17. // YY. M. DD.-> YYMMDD export function formatDateForQueryString(dateString) { const splitArray = dateString.split('.’); splitArray.map((el, i, arr) => { arr[i] = el.replace(/ /gi, '').length === 1 ? '0' + el : el; }); return result.join('').replace(/ /gi, ''); } Code easy to test // dateHelper.test.js describe('formatDateForQueryString function', () => { describe(‘converts a string in format “YY. M. DD.”', () => { test(‘to a string in “YYMMDD”.', () => { const actual = formatDateForQueryString('18. 1. 10.'); expect(actual).toBe('180110'); }); }); }); Don’t change the test codes Function that converts a string in format 'YY. M. DD. ' to a string in format 'YYMMDD'
  • 18. // YY. M. DD.-> YYMMDD export function formatDateForQueryString(dateString) { const splitArray = dateString.split('.’); splitArray.map((el, i, arr) => { arr[i] = el.replace(/ /gi, '').length === 1 ? '0' + el : el; }); return result.join('').replace(/ /gi, ''); } Code easy to test export function formatDateForQueryString(dateString) { return `${dateString} ` .split('. ') .map(x => (x.length === 1 ? `0${x}` : x)) .join(''); } The refactoring should be limited to the extent that the test is not broken. Refactor
  • 19. Ex. Maybe almost? Separate only those codes that are easy to test from those that are made difficult to test. Code easy to test Code hard to test Production code Parts include high-value business logic Buggy code (current, not past) Low coupling and complex logic* Where can I find it? *Low or no external dependency (independent environment) and business logic is complex (Replace username to email, etc.)
  • 20. Code hard to test easy hard easy Overall flow Find the testable code, Separate them, Add test code, And Refactor Refactor Red Green or
  • 21. class RegistrationFormContainer extends Component { / * (Omitted) Methods on modal behavior * / handleSubmit = async () => { const { validValues } = this.props.form; const phone = validValues.phone ? '+82' + validValues.phone.slice(1) : null; const command = { username: validValues.username || validValues.email, email: validValues.email, phone: phone, }; try { await postRegisterRequest(command); this.closeModal(); } catch (err) { Modal.error({ /* ... */ }); } }; render() { /* ... */ } } } Code hard to test * React code This contains important business logic. Why this code is difficult to test • API request • Different UI depending on the result of the response Only separate testable parts  API request
  • 22. function formatRegisterCommand() { const { validValues } = this.props.form; const phone = validValues.phone ? '+82' + validValues.phone.slice(1) : null; const command = { username: validValues.username || validValues.email, email: validValues.email, phone: phone, }; return command; } export default formatRegisterCommand; import formatRegisterCommand /* ... */ describe('formatRegisterCommand function ', () => { test(‘does not throw error.', () => { expect(formatRegisterCommand).not.toThrowError(); }); }); UTF-8 LF JavaScript React Prettier: formatRegisterCommand.js formatRegisterCommand.test.js
  • 23. function formatRegisterCommand() { const { validValues } = this.props.form; const phone = validValues.phone ? '+82' + validValues.phone.slice(1) : null; const command = { username: validValues.username || validValues.email, email: validValues.email, phone: phone, }; return command; } export default formatRegisterCommand; import formatRegisterCommand /* ... */ describe('formatRegisterCommand function ', () => { test(‘does not throw error.', () => { expect(formatRegisterCommand).not.toThrowError(); }); }); UTF-8 LF JavaScript React Prettier: formatRegisterCommand.js formatRegisterCommand.test.js Removes framework-dependent (=external dependency) code
  • 24. function formatRegisterCommand(validValues={}){ const phone = validValues.phone ? '+82' + validValues.phone.slice(1) : null; const command = { username: validValues.username || validValues.email, email: validValues.email, phone: phone, }; return command; } export default formatRegisterCommand; import formatRegisterCommand /* ... */ describe('formatRegisterCommand function ', () => { test(‘does not throw error.', () => { expect(formatRegisterCommand).not.toThrowError(); }); }); UTF-8 LF JavaScript React Prettier: formatRegisterCommand.js formatRegisterCommand.test.js Make it an independent function that is not affected externally
  • 25. function formatRegisterCommand(validValues={}){ const phone = validValues.phone ? '+82' + validValues.phone.slice(1) : null; const command = { username: validValues.username || validValues.email, email: validValues.email, phone: phone, }; return command; } export default formatRegisterCommand; /* ... */ describe('returns a command', () => { const param = { username: 'user', email: 'user@email.com', phone: '01012345678', agreement: [true, true, true], }; describe('whose username property should be', () => { test('the same as the username of the argument.’, () => { const actual = formatRegisterCommand(param); expect(actual.username).toBe(param.username); }); }); }); UTF-8 LF JavaScript React Prettier: formatRegisterCommand.js formatRegisterCommand.test.js Add a spec about the return value
  • 26. Develop new code with TDD. 1-3
  • 27. I received additional business requirements. "A user must agree all the terms to sign up."
  • 28. /* ... */ describe('whose agreement property should be', () => { test('return false when any of the arguments are false',()=> { const actual = formatRegisterCommand({ ...param, agreement: [true, true, false], }); expect(actual).toBe(false); }); }); /* ... */ UTF-8 LF JavaScript React Prettier: formatRegisterCommand.js formatRegisterCommand.test.js function formatRegisterCommand(source = {}) { const { username, email, phone } = source; return { username: username || email, email, phone: phone ? `+82${phone.slice(1)}` : null, }; } export default formatRegisterCommand;
  • 29. /* ... */ describe('whose agreement property should be', () => { test('return false when any of the arguments are false',()=> { const actual = formatRegisterCommand({ ...param, agreement: [true, true, false], }); expect(actual).toBe(false); }); }); /* ... */ UTF-8 LF JavaScript React Prettier: formatRegisterCommand.js formatRegisterCommand.test.js function formatRegisterCommand(source = {}) { const { username, email, phone } = source; if (source.agreement.some(agree => !agree)) { return false; } return { username: username || email, email, phone: phone ? `+82${phone.slice(1)}` : null, }; } export default formatRegisterCommand; if (source.agreement.some(agree => !agree)) { return false; }
  • 31. 1. Adding tests to legacy code (+Refactor) 2. Develop new code with TDD. HOW: Follows below cycle Separate as function Refactor Add test code WHAT: Codes easy to test - Parts includes high-value business logic - The spot where the bug was found (formerly X) - Low coupling and complex logic TLD 1. Add tests to code that is already easy to test. 2. Make your code easy to test, and then test. TDD - Where to add new features
  • 32. REAL Benefits. I felt while doing TLD & TDD.
  • 33. Less anxious, Less stress Things I really felt while doing TEST.
  • 34. /* ... */ describe('formatRegisterCommand function', () => { test(‘does not throw error.', () => { expect(formatRegisterCommand).not.toThrowError(); }); }); describe(‘whose agreement property should be', () => { test('return false when any of the arguments are fal => { const actual = formatRegisterCommand({ ...param, agreement: [true, true, false], }); expect(actual).toBe(false); }); }); /* ... */ UTF-8 LF JavaScript React Prettier: formatRegisterCommand.js formatRegisterCommand.test.js function formatRegisterCommand(source = {}) { const { username, email, phone } = source; if (source.agreement.some(agree => !agree)) { return false; } return { username: username || email, email, phone: phone ? `+82${phone.slice(1)}` : null, }; } export default formatRegisterCommand; if (source.agreement.some(agree => !agree)) { return false; } FAIL src/business/formatRegisterCommand.test.js ● formatRegisterCommand function › does not throw error. expect(function).not.toThrowError() Expected the function not to throw an error. Instead, it threw: TypeError: Cannot read property 'some' of undefined at formatRegisterCommand (src/business/formatRegisterCommand.js:9:17) /* ... */ formatRegisterCommand function ✓ does not throw error. return command UTF-8 LF JavaScript React Prettier:
  • 35. The test code makes me to find the code smell pretty often. Things I really felt while doing TEST. Improve the design of code
  • 36. PASS src/business/formatRegisterCommand.test.js formatRegisterCommand function ✓ does not throw error. return command whose username property should be ✓ equal to username value of argument. ✓ equal to email value of argument when username value is falsy value. whose email property should be ✓ equal to email value of argument. whose phone property should be ✓ the value of phone property of argument that changed the first 0 to .. whose agreement property should be ✓ return false when any of the arguments are false. For example,
  • 37. PASS src/business/formatRegisterCommand.test.js formatRegisterCommand function ✓ does not throw error. return command whose username property should be ✓ equal to username value of argument. ✓ equal to email value of argument when username value is falsy value. whose email property should be ✓ equal to email value of argument. whose phone property should be ✓ the value of phone property of argument that changed the first 0 to .. whose agreement property should be ✓ return false when any of the arguments are false. For example, 2 Type of return value. - command object - false 2 Responsibilities. - Decide whether user can join - Format input values to command object
  • 38. formatRegisterCommand.js function formatRegisterCommand(source = {}) { const { username, email, phone } = source; const agreement = source.agreement || []; if (agreement.some(agree => !agree)) return false; return { username: username || email, email, phone: phone ? `+82${phone.slice(1)}` : null, }; } export default formatRegisterCommand; UTF-8 LF JavaScript React Prettier:
  • 39. I realize how bad design skills I have. So I'm interested in stable code and good design. Motivation for learning Things I really felt while doing TEST & TDD.
  • 40. Bug tracking time is significantly reduced. Improve development productivity * Time saved without testing ≤ Time to fix a bug from not tested code * It’s my subjective feeling. No objectivity. Things I really felt while doing TEST & TDD.
  • 41. I've found some loopholes in business logic *in advance. Improve project productivity *Before I (or we) start coding Things I really felt while doing TDD.
  • 42. TDD controls that I don’t do more than one thing at a time. It makes me focus more on what I have to do right now. Concentration is improved Things I really felt while doing TDD.
  • 43. Original article: https://www.facebook.com/notes/kent-beck/rip-tdd/750840194948847/ RIP TDD: The article criticizes DHH's article, "TDD is dead." In this article, Kent Beck mentions the benefits of TDD. - Over-engineering. I have a tendency to "throw in" functionality I "know" I'm "going to need". Making one red test green (along with the list of future tests) helps me implement just enough. I need to find a new way to stay focused.