SlideShare a Scribd company logo
1 of 31
Download to read offline
Test and Refactoring
SungMin Han
1
2
3
Introduction to Test
The qualityof Code
User scenario
Contents
Introduction to Test
Testing shows the presence, not the absence, of bugs.
In other words, a program can be proven incorrect by a
test, but it cannot be proven correct.
Robert C Martin
Clean Architecture: A Craftsman's Guide to Software Structure and Design
Introduction to Test
Let’s look at the code
Output: 3
def add(*args):
if	len(list(filter(lambda	n:	not	str(n).isdigit(),	args)))	> 0:
raise	Exception('argument	must	be	used	number	type')
return	sum(args)
def main():
a	= 1
b	= 2
print(add(a,	b))
if	__name__	==	'__main__':
main()
def add(*args):
if	len(list(filter(lambda	n:	not	str(n).isdigit(),	args)))	> 0:
raise	Exception('argument	must	be	used	number	type')
return	sum(args)
def main():
a	= ’a’
b	= 3
print(add(a,	b))
if	__name__	==	'__main__':
main()
Introduction to Test
Let’s look at the code
How about when argument given str type?
Introduction to Test
Let’s look at the code
Okay seems working well.
(The code throws Exception, Which is designed)
Introduction to Test
Let’s look at the code
When it will be happened, If we give number-like string as input to add func?
def add(*args):
if	len(list(filter(lambda	n:	not	str(n).isdigit(),	args)))	> 0:
raise	Exception('argument	must	be	used	number	type')
return	sum(args)
def main():
a	= ’3’
b	= 1
print(add(a,	b))
if	__name__	==	'__main__':
main()
Introduction to Test
Let’s look at the code
Oh...
Introduction to Test
The problem is
We can not expect all of user input.
Most of case,
User try to put some exceptional input (At least, The exception at the code, not Business)
And those input occurs not-expected bugs or failing.
You have to admit
Bugs are able to be happened every time, every where.
Introduction to Test
The purpose of test is quite simple.
Thinking all of the cases (aka. `TestCases`)
And make them to covered under those cases.
Introduction to Test
Back to the code
How can we prevent this exceptional bugs?
def add(*args):
if	len(list(filter(lambda	n:	not	str(n).isdigit(),	args)))	> 0:
raise	Exception('argument	must	be	used	number	type')
return	sum(args)
def main():
a	= ’3’
b	= 1
print(add(a,	b))
if	__name__	==	'__main__':
main()
Introduction to Test
Simple test cases
Right code block will cover for general scenarios input.
def add(*args):
if	len(list(filter(lambda	n:	not	str(n).isdigit(),	args)))	> 0:
raise	Exception('argument	must	be	used	number	type')
return	sum(*args)
def main():
a	= 2	
b	= 1
print(add(a,	b))
if	__name__	==	'__main__':
main()
import	unittest
from	main import	main,	add
class	TestSumFunction(unittest.TestCase):
def test_main(self):
try:
main()
except:
self.fail('should	not	throws	any'
'	error	when	we	call	main	func')
def test_sum_with_numeric_args(self):
self.assertEqual(3, add(1,	2),
'should	returns	3	when	given	1,	2	in	add	func')
Introduction to Test
The result of test codes
Test result seems just Okay.
Okay is not okay, Test has to cover perfect.
Introduction to Test
Add more test scenarios.
These cases are going to cover more scenarios of user input.
def test_sum_with_numeric_like_str_args(self):
try:
add('1',	'2')
except	Exception	as	e:
self.assertEqual('argument	must	be	used	number	type',	str(e),
'should	raises	`argument	must	be	used	number	type`	message'
'when	given	`1`,	`2`	in	add	func')
return
self.fail('should	raises	an	Exception	when	given	`1`,	`2`	in	add	func')
def test_sum_with_combination_tuple_args(self):
try:
add((1,	2),	3)
except	Exception	as	e:
self.assertEqual('argument	must	be	used	number	type', str(e),
'should	raises	`argument	must	be	used	number	type`	message'
'when	given	(1,	2),	3	in	add	func')
return
self.fail('should	raises	an	Exception	when	given	(1,	2)	in	add	func')
Introduction to Test
And look, We have got some new!
When numeric-like string is given, The code will worked to unexpected way.
Introduction to Test
Test will fix the code reasonably.
Finally, we can fix the code, By a result of unit test.
This is how to work based on Test.
def add(*args):
if	len(list(filter(lambda	n:	not	str(n).isdigit(),	args)))	> 0:
raise	Exception('argument	must	be	used	number	type')
return	sum(args)	
def add(*args):
if	len(list(filter(lambda	n:	not	isinstance(n,	numbers.Number),	args)))	> 0:
raise	Exception('argument	must	be	used	number	type')
return	sum(args)
Introduction to Test
There are so many types of test.
Unit test
Verify, Indivisual, Isolated
(like func, simple call)
Integration test
harmony, together with Unit test than one
more complex than Unit test
End to end test (aka. e2e test)
Robot script or higher level working script
will give an action like a human
(like Selenium test, Night watch test etc)
UI Test
User interface test
The pixel level must be equal as expected
(like Naver search button similarity
When finish to update at dev stage)
Introduction to Test
Let’s look how facebook test e2e well.
https://youtu.be/diYgXpktTqo?t=649
Introduction to Test
There are simple rule when you want to make unit test codes.
We do test, It, because
Steve Sanderson’s Blog (ASP.NET developer)
http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/
And please This is basic rules
- Ignore test result after finish write up codes
- Change test spec frequently without coworkers
agreement
- Don’t test persistence layer
- Make function as pure or Use mock in testing inpure
function
The quality of codes
QA and Development should be working together to
ensure the quality of the system.
Robert C Martin
The Clean Coder: A Code of Conduct for Professional Programmers
About broken window theory
One broken window, left unrepaired for any substantial
length of time, instills in the inhabitants of the building a
sense of abandonment—
a sense that the powers that be don’t care about the building. So another window gets
broken. People start littering. Graffiti appears.
Serious structural damage begins. In a relatively short space of time, the building
becomes damaged beyond the owner’s desire to fix it, and the sense of abandonment
becomes reality.
The boy scout rule
“Always leave the code you’re editing
a little better than you found it”
Robert C. Martin
The quality of codes
Let’s think a simple scenario.
import	requests
def get_user_session():
#	this	function	look	inside	cache	layer
#	and	user	session,	and	return	your	session	matched	account	key
return	'somekey'
def login(id,	pw):
r	=	requests.get('https://nid.naver.com?id=' +	id,	'&pw='	+	pw)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
session	=	get_user_session()
if	session is	not	None:
r	=	requests.get('https://nid.naver.com?key='	+	session)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
raise	Exception('your	account	cannot	be	found')
def main():
id	=	'id'
pw	=	'pw'
login(id,	pw)
if	__name__	==	'__main__':
main()
The quality of codes
Let’s think a simple scenario.
import	requests
def get_user_session():
#	this	function	look	inside	cache	layer
#	and	user	session,	and	return	your	session	matched	account	key
return	'somekey'
def login(id,	pw):
r	=	requests.get('https://nid.naver.com?id=' +	id,	'&pw='	+	pw)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
session	=	get_user_session()
if	session is	not	None:
r	=	requests.get('https://nid.naver.com?key='	+	session)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
raise	Exception('your	account	cannot	be	found')
def main():
id	=	'id'
pw	=	'pw'
login(id,	pw)
if	__name__	==	'__main__':
main()
Don’t hard code URI.
Because URI can be changed,
even if the service is clear and official.
The quality of codes
Let’s think a simple scenario.
import	requests
def get_user_session():
#	this	function	look	inside	cache	layer
#	and	user	session,	and	return	your	session	matched	account	key
return	'somekey'
def login(id,	pw):
r	=	requests.get('https://nid.naver.com?id=' +	id,	'&pw='	+	pw)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
session	=	get_user_session()
if	session is	not	None:
r	=	requests.get('https://nid.naver.com?key='	+	session)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
raise	Exception('your	account	cannot	be	found')
def main():
id	=	'id'
pw	=	'pw'
login(id,	pw)
if	__name__	==	'__main__':
main()
Code seem duplicated
Make them as new small function
Don’t be a worry when you add
a lot of function for avoiding duplication
The quality of codes
Let’s think a simple scenario.
import	requests
def get_user_session():
#	this	function	look	inside	cache	layer
#	and	user	session,	and	return	your	session	matched	account	key
return	'somekey'
def login(id,	pw):
r	=	requests.get('https://nid.naver.com?id=' +	id,	'&pw='	+	pw)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
session	=	get_user_session()
if	session is	not	None:
r	=	requests.get('https://nid.naver.com?key='	+	session)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
raise	Exception('your	account	cannot	be	found')
def main():
id	=	'id'
pw	=	'pw'
login(id,	pw)
if	__name__	==	'__main__':
main()
So deep indent, And this is useless
Use guard clause this
or make them to another function
deep indent is always bad
The quality of codes
Let’s think a simple scenario.
import	requests
def get_user_session():
#	this	function	look	inside	cache	layer
#	and	user	session,	and	return	your	session	matched	account	key
return	'somekey'
def login(id,	pw):
r	=	requests.get('https://nid.naver.com?id=' +	id,	'&pw='	+	pw)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
session	=	get_user_session()
if	session is	not	None:
r	=	requests.get('https://nid.naver.com?key='	+	session)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
raise	Exception('your	account	cannot	be	found')
def main():
id	=	'id'
pw	=	'pw'
login(id,	pw)
if	__name__	==	'__main__':
main()
Also deep indent
The quality of codes
Let’s think a simple scenario.
import	requests
def get_user_session():
#	this	function	look	inside	cache	layer
#	and	user	session,	and	return	your	session	matched	account	key
return	'somekey'
def login(id,	pw):
r	=	requests.get('https://nid.naver.com?id=' +	id,	'&pw='	+	pw)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
session	=	get_user_session()
if	session is	not	None:
r	=	requests.get('https://nid.naver.com?key='	+	session)
res	=	r.json()
if	res.code ==	200:
return	res.account
else:
raise	Exception('your	account	cannot	be	found')
def main():
id	=	'id'
pw	=	'pw'
login(id,	pw)
if	__name__	==	'__main__':
main()
String concatenated by + operator
Use interpolation or
params argument of requests.get func
+ operator will be tough when you change
param name or value for future.
https://www.youtube.com/watch?v=_NnElPO5BU0
User scenario
User scenario
How can we learn more, this kinda trick?
https://refactoring.guru/inline-class
https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it
https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
DRY rule
YAGNI rule
Thank you

More Related Content

What's hot

Rechecking SharpDevelop: Any New Bugs?
Rechecking SharpDevelop: Any New Bugs?Rechecking SharpDevelop: Any New Bugs?
Rechecking SharpDevelop: Any New Bugs?PVS-Studio
 
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDKEric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDKGuardSquare
 
重構—改善既有程式的設計(chapter 9)
重構—改善既有程式的設計(chapter 9)重構—改善既有程式的設計(chapter 9)
重構—改善既有程式的設計(chapter 9)Chris Huang
 
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...Istanbul Tech Talks
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012Yaqi Zhao
 
Flex Maniacs 2007
Flex Maniacs 2007Flex Maniacs 2007
Flex Maniacs 2007rtretola
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test frameworkAbner Chih Yi Huang
 
ProGuard / DexGuard Tips and Tricks
ProGuard / DexGuard Tips and TricksProGuard / DexGuard Tips and Tricks
ProGuard / DexGuard Tips and Tricksnetomi
 
[2012 02 03]clean_code 4장
[2012 02 03]clean_code 4장[2012 02 03]clean_code 4장
[2012 02 03]clean_code 4장Jong Pil Won
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitMichelangelo van Dam
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDPaweł Michalik
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitMichelangelo van Dam
 
Fnt software solutions placement paper
Fnt software solutions placement paperFnt software solutions placement paper
Fnt software solutions placement paperfntsofttech
 

What's hot (20)

TDD, BDD and mocks
TDD, BDD and mocksTDD, BDD and mocks
TDD, BDD and mocks
 
Clean code
Clean codeClean code
Clean code
 
Rechecking SharpDevelop: Any New Bugs?
Rechecking SharpDevelop: Any New Bugs?Rechecking SharpDevelop: Any New Bugs?
Rechecking SharpDevelop: Any New Bugs?
 
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDKEric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
Eric Lafortune - ProGuard: Optimizer and obfuscator in the Android SDK
 
GMock framework
GMock frameworkGMock framework
GMock framework
 
重構—改善既有程式的設計(chapter 9)
重構—改善既有程式的設計(chapter 9)重構—改善既有程式的設計(chapter 9)
重構—改善既有程式的設計(chapter 9)
 
Clean code
Clean codeClean code
Clean code
 
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012
 
Flex Maniacs 2007
Flex Maniacs 2007Flex Maniacs 2007
Flex Maniacs 2007
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test framework
 
ProGuard / DexGuard Tips and Tricks
ProGuard / DexGuard Tips and TricksProGuard / DexGuard Tips and Tricks
ProGuard / DexGuard Tips and Tricks
 
Phpunit testing
Phpunit testingPhpunit testing
Phpunit testing
 
[2012 02 03]clean_code 4장
[2012 02 03]clean_code 4장[2012 02 03]clean_code 4장
[2012 02 03]clean_code 4장
 
Introduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnitIntroduction to Unit Testing with PHPUnit
Introduction to Unit Testing with PHPUnit
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
Fnt software solutions placement paper
Fnt software solutions placement paperFnt software solutions placement paper
Fnt software solutions placement paper
 
Test Engine
Test EngineTest Engine
Test Engine
 
Tdd.eng.ver
Tdd.eng.verTdd.eng.ver
Tdd.eng.ver
 

Similar to Test and refactoring

Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test communityKerry Buckley
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003R696
 
Top 10 C# projects errors found in 2016
Top 10 C# projects errors found in 2016Top 10 C# projects errors found in 2016
Top 10 C# projects errors found in 2016PVS-Studio
 
Class 12 computer sample paper with answers
Class 12 computer sample paper with answersClass 12 computer sample paper with answers
Class 12 computer sample paper with answersdebarghyamukherjee60
 
Optimization in the world of 64-bit errors
Optimization  in the world of 64-bit errorsOptimization  in the world of 64-bit errors
Optimization in the world of 64-bit errorsPVS-Studio
 
Claguage 110226222227-phpapp02
Claguage 110226222227-phpapp02Claguage 110226222227-phpapp02
Claguage 110226222227-phpapp02CIMAP
 
Write codeforhumans
Write codeforhumansWrite codeforhumans
Write codeforhumansNarendran R
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 
Acceptance Testing With Selenium
Acceptance Testing With SeleniumAcceptance Testing With Selenium
Acceptance Testing With Seleniumelliando dias
 
Compiler lab final report writing
Compiler lab final report writingCompiler lab final report writing
Compiler lab final report writingUmme habiba
 
cpp-streams.ppt,C++ is the top choice of many programmers for creating powerf...
cpp-streams.ppt,C++ is the top choice of many programmers for creating powerf...cpp-streams.ppt,C++ is the top choice of many programmers for creating powerf...
cpp-streams.ppt,C++ is the top choice of many programmers for creating powerf...bhargavi804095
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstractionIntro C# Book
 
NPTEL QUIZ.docx
NPTEL QUIZ.docxNPTEL QUIZ.docx
NPTEL QUIZ.docxGEETHAR59
 
Analysis of Microsoft Code Contracts
Analysis of Microsoft Code ContractsAnalysis of Microsoft Code Contracts
Analysis of Microsoft Code ContractsPVS-Studio
 
The First C# Project Analyzed
The First C# Project AnalyzedThe First C# Project Analyzed
The First C# Project AnalyzedPVS-Studio
 
Reanalyzing the Notepad++ project
Reanalyzing the Notepad++ projectReanalyzing the Notepad++ project
Reanalyzing the Notepad++ projectPVS-Studio
 

Similar to Test and refactoring (20)

Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
 
Top 10 C# projects errors found in 2016
Top 10 C# projects errors found in 2016Top 10 C# projects errors found in 2016
Top 10 C# projects errors found in 2016
 
Class 12 computer sample paper with answers
Class 12 computer sample paper with answersClass 12 computer sample paper with answers
Class 12 computer sample paper with answers
 
Optimization in the world of 64-bit errors
Optimization  in the world of 64-bit errorsOptimization  in the world of 64-bit errors
Optimization in the world of 64-bit errors
 
Claguage 110226222227-phpapp02
Claguage 110226222227-phpapp02Claguage 110226222227-phpapp02
Claguage 110226222227-phpapp02
 
Rspec
RspecRspec
Rspec
 
Write codeforhumans
Write codeforhumansWrite codeforhumans
Write codeforhumans
 
CPP Homework Help
CPP Homework HelpCPP Homework Help
CPP Homework Help
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Acceptance Testing With Selenium
Acceptance Testing With SeleniumAcceptance Testing With Selenium
Acceptance Testing With Selenium
 
Compiler lab final report writing
Compiler lab final report writingCompiler lab final report writing
Compiler lab final report writing
 
cpp-streams.ppt,C++ is the top choice of many programmers for creating powerf...
cpp-streams.ppt,C++ is the top choice of many programmers for creating powerf...cpp-streams.ppt,C++ is the top choice of many programmers for creating powerf...
cpp-streams.ppt,C++ is the top choice of many programmers for creating powerf...
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstraction
 
NPTEL QUIZ.docx
NPTEL QUIZ.docxNPTEL QUIZ.docx
NPTEL QUIZ.docx
 
Analysis of Microsoft Code Contracts
Analysis of Microsoft Code ContractsAnalysis of Microsoft Code Contracts
Analysis of Microsoft Code Contracts
 
The First C# Project Analyzed
The First C# Project AnalyzedThe First C# Project Analyzed
The First C# Project Analyzed
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
Reanalyzing the Notepad++ project
Reanalyzing the Notepad++ projectReanalyzing the Notepad++ project
Reanalyzing the Notepad++ project
 

More from Kenneth Ceyer

이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020Kenneth Ceyer
 
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.Kenneth Ceyer
 
LP(linear programming) Algorithm
LP(linear programming) AlgorithmLP(linear programming) Algorithm
LP(linear programming) AlgorithmKenneth Ceyer
 
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019Kenneth Ceyer
 
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019 하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019 Kenneth Ceyer
 
AllReduce for distributed learning I/O Extended Seoul
AllReduce for distributed learning I/O Extended SeoulAllReduce for distributed learning I/O Extended Seoul
AllReduce for distributed learning I/O Extended SeoulKenneth Ceyer
 
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019Kenneth Ceyer
 
Deep dive into Modern frameworks - HTML5 Forum 2018
Deep dive into Modern frameworks - HTML5 Forum 2018Deep dive into Modern frameworks - HTML5 Forum 2018
Deep dive into Modern frameworks - HTML5 Forum 2018Kenneth Ceyer
 
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018Kenneth Ceyer
 
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기Kenneth Ceyer
 
엔지니어 관점에서 바라본 데이터시각화
엔지니어 관점에서 바라본 데이터시각화엔지니어 관점에서 바라본 데이터시각화
엔지니어 관점에서 바라본 데이터시각화Kenneth Ceyer
 
Dealing with Python Reactively - PyCon Korea 2017
Dealing with Python Reactively - PyCon Korea 2017Dealing with Python Reactively - PyCon Korea 2017
Dealing with Python Reactively - PyCon Korea 2017Kenneth Ceyer
 
파이썬 리액티브하게 짜기 - PyCon Korea 2017
파이썬 리액티브하게 짜기 - PyCon Korea 2017파이썬 리액티브하게 짜기 - PyCon Korea 2017
파이썬 리액티브하게 짜기 - PyCon Korea 2017Kenneth Ceyer
 
AngularJS 2, version 1 and ReactJS
AngularJS 2, version 1 and ReactJSAngularJS 2, version 1 and ReactJS
AngularJS 2, version 1 and ReactJSKenneth Ceyer
 

More from Kenneth Ceyer (15)

이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
이미지 프로세싱 in Python Open Source - PYCON KOREA 2020
 
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
정적 컨텐츠 제너레이터 GatsbyJS에 대해서 알아봅시다.
 
LP(linear programming) Algorithm
LP(linear programming) AlgorithmLP(linear programming) Algorithm
LP(linear programming) Algorithm
 
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
AI 연구자를 위한 클린코드 - GDG DevFest Seoul 2019
 
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019 하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
하둡 에코시스템 위에서 환상적인 테이크오프 - DSTS 2019
 
AllReduce for distributed learning I/O Extended Seoul
AllReduce for distributed learning I/O Extended SeoulAllReduce for distributed learning I/O Extended Seoul
AllReduce for distributed learning I/O Extended Seoul
 
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
gRPC와 goroutine 톺아보기 - GDG Golang Korea 2019
 
How to use vim
How to use vimHow to use vim
How to use vim
 
Deep dive into Modern frameworks - HTML5 Forum 2018
Deep dive into Modern frameworks - HTML5 Forum 2018Deep dive into Modern frameworks - HTML5 Forum 2018
Deep dive into Modern frameworks - HTML5 Forum 2018
 
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
우아하게 준비하는 테스트와 리팩토링 - PyCon Korea 2018
 
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 
엔지니어 관점에서 바라본 데이터시각화
엔지니어 관점에서 바라본 데이터시각화엔지니어 관점에서 바라본 데이터시각화
엔지니어 관점에서 바라본 데이터시각화
 
Dealing with Python Reactively - PyCon Korea 2017
Dealing with Python Reactively - PyCon Korea 2017Dealing with Python Reactively - PyCon Korea 2017
Dealing with Python Reactively - PyCon Korea 2017
 
파이썬 리액티브하게 짜기 - PyCon Korea 2017
파이썬 리액티브하게 짜기 - PyCon Korea 2017파이썬 리액티브하게 짜기 - PyCon Korea 2017
파이썬 리액티브하게 짜기 - PyCon Korea 2017
 
AngularJS 2, version 1 and ReactJS
AngularJS 2, version 1 and ReactJSAngularJS 2, version 1 and ReactJS
AngularJS 2, version 1 and ReactJS
 

Recently uploaded

Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxAnnaArtyushina1
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...masabamasaba
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...chiefasafspells
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfkalichargn70th171
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 

Recently uploaded (20)

Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 

Test and refactoring

  • 2. 1 2 3 Introduction to Test The qualityof Code User scenario Contents
  • 3. Introduction to Test Testing shows the presence, not the absence, of bugs. In other words, a program can be proven incorrect by a test, but it cannot be proven correct. Robert C Martin Clean Architecture: A Craftsman's Guide to Software Structure and Design
  • 4. Introduction to Test Let’s look at the code Output: 3 def add(*args): if len(list(filter(lambda n: not str(n).isdigit(), args))) > 0: raise Exception('argument must be used number type') return sum(args) def main(): a = 1 b = 2 print(add(a, b)) if __name__ == '__main__': main()
  • 5. def add(*args): if len(list(filter(lambda n: not str(n).isdigit(), args))) > 0: raise Exception('argument must be used number type') return sum(args) def main(): a = ’a’ b = 3 print(add(a, b)) if __name__ == '__main__': main() Introduction to Test Let’s look at the code How about when argument given str type?
  • 6. Introduction to Test Let’s look at the code Okay seems working well. (The code throws Exception, Which is designed)
  • 7. Introduction to Test Let’s look at the code When it will be happened, If we give number-like string as input to add func? def add(*args): if len(list(filter(lambda n: not str(n).isdigit(), args))) > 0: raise Exception('argument must be used number type') return sum(args) def main(): a = ’3’ b = 1 print(add(a, b)) if __name__ == '__main__': main()
  • 8. Introduction to Test Let’s look at the code Oh...
  • 9. Introduction to Test The problem is We can not expect all of user input. Most of case, User try to put some exceptional input (At least, The exception at the code, not Business) And those input occurs not-expected bugs or failing. You have to admit Bugs are able to be happened every time, every where.
  • 10. Introduction to Test The purpose of test is quite simple. Thinking all of the cases (aka. `TestCases`) And make them to covered under those cases.
  • 11. Introduction to Test Back to the code How can we prevent this exceptional bugs? def add(*args): if len(list(filter(lambda n: not str(n).isdigit(), args))) > 0: raise Exception('argument must be used number type') return sum(args) def main(): a = ’3’ b = 1 print(add(a, b)) if __name__ == '__main__': main()
  • 12. Introduction to Test Simple test cases Right code block will cover for general scenarios input. def add(*args): if len(list(filter(lambda n: not str(n).isdigit(), args))) > 0: raise Exception('argument must be used number type') return sum(*args) def main(): a = 2 b = 1 print(add(a, b)) if __name__ == '__main__': main() import unittest from main import main, add class TestSumFunction(unittest.TestCase): def test_main(self): try: main() except: self.fail('should not throws any' ' error when we call main func') def test_sum_with_numeric_args(self): self.assertEqual(3, add(1, 2), 'should returns 3 when given 1, 2 in add func')
  • 13. Introduction to Test The result of test codes Test result seems just Okay. Okay is not okay, Test has to cover perfect.
  • 14. Introduction to Test Add more test scenarios. These cases are going to cover more scenarios of user input. def test_sum_with_numeric_like_str_args(self): try: add('1', '2') except Exception as e: self.assertEqual('argument must be used number type', str(e), 'should raises `argument must be used number type` message' 'when given `1`, `2` in add func') return self.fail('should raises an Exception when given `1`, `2` in add func') def test_sum_with_combination_tuple_args(self): try: add((1, 2), 3) except Exception as e: self.assertEqual('argument must be used number type', str(e), 'should raises `argument must be used number type` message' 'when given (1, 2), 3 in add func') return self.fail('should raises an Exception when given (1, 2) in add func')
  • 15. Introduction to Test And look, We have got some new! When numeric-like string is given, The code will worked to unexpected way.
  • 16. Introduction to Test Test will fix the code reasonably. Finally, we can fix the code, By a result of unit test. This is how to work based on Test. def add(*args): if len(list(filter(lambda n: not str(n).isdigit(), args))) > 0: raise Exception('argument must be used number type') return sum(args) def add(*args): if len(list(filter(lambda n: not isinstance(n, numbers.Number), args))) > 0: raise Exception('argument must be used number type') return sum(args)
  • 17. Introduction to Test There are so many types of test. Unit test Verify, Indivisual, Isolated (like func, simple call) Integration test harmony, together with Unit test than one more complex than Unit test End to end test (aka. e2e test) Robot script or higher level working script will give an action like a human (like Selenium test, Night watch test etc) UI Test User interface test The pixel level must be equal as expected (like Naver search button similarity When finish to update at dev stage)
  • 18. Introduction to Test Let’s look how facebook test e2e well. https://youtu.be/diYgXpktTqo?t=649
  • 19. Introduction to Test There are simple rule when you want to make unit test codes. We do test, It, because Steve Sanderson’s Blog (ASP.NET developer) http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/ And please This is basic rules - Ignore test result after finish write up codes - Change test spec frequently without coworkers agreement - Don’t test persistence layer - Make function as pure or Use mock in testing inpure function
  • 20. The quality of codes QA and Development should be working together to ensure the quality of the system. Robert C Martin The Clean Coder: A Code of Conduct for Professional Programmers
  • 21. About broken window theory One broken window, left unrepaired for any substantial length of time, instills in the inhabitants of the building a sense of abandonment— a sense that the powers that be don’t care about the building. So another window gets broken. People start littering. Graffiti appears. Serious structural damage begins. In a relatively short space of time, the building becomes damaged beyond the owner’s desire to fix it, and the sense of abandonment becomes reality.
  • 22. The boy scout rule “Always leave the code you’re editing a little better than you found it” Robert C. Martin
  • 23. The quality of codes Let’s think a simple scenario. import requests def get_user_session(): # this function look inside cache layer # and user session, and return your session matched account key return 'somekey' def login(id, pw): r = requests.get('https://nid.naver.com?id=' + id, '&pw=' + pw) res = r.json() if res.code == 200: return res.account else: session = get_user_session() if session is not None: r = requests.get('https://nid.naver.com?key=' + session) res = r.json() if res.code == 200: return res.account else: raise Exception('your account cannot be found') def main(): id = 'id' pw = 'pw' login(id, pw) if __name__ == '__main__': main()
  • 24. The quality of codes Let’s think a simple scenario. import requests def get_user_session(): # this function look inside cache layer # and user session, and return your session matched account key return 'somekey' def login(id, pw): r = requests.get('https://nid.naver.com?id=' + id, '&pw=' + pw) res = r.json() if res.code == 200: return res.account else: session = get_user_session() if session is not None: r = requests.get('https://nid.naver.com?key=' + session) res = r.json() if res.code == 200: return res.account else: raise Exception('your account cannot be found') def main(): id = 'id' pw = 'pw' login(id, pw) if __name__ == '__main__': main() Don’t hard code URI. Because URI can be changed, even if the service is clear and official.
  • 25. The quality of codes Let’s think a simple scenario. import requests def get_user_session(): # this function look inside cache layer # and user session, and return your session matched account key return 'somekey' def login(id, pw): r = requests.get('https://nid.naver.com?id=' + id, '&pw=' + pw) res = r.json() if res.code == 200: return res.account else: session = get_user_session() if session is not None: r = requests.get('https://nid.naver.com?key=' + session) res = r.json() if res.code == 200: return res.account else: raise Exception('your account cannot be found') def main(): id = 'id' pw = 'pw' login(id, pw) if __name__ == '__main__': main() Code seem duplicated Make them as new small function Don’t be a worry when you add a lot of function for avoiding duplication
  • 26. The quality of codes Let’s think a simple scenario. import requests def get_user_session(): # this function look inside cache layer # and user session, and return your session matched account key return 'somekey' def login(id, pw): r = requests.get('https://nid.naver.com?id=' + id, '&pw=' + pw) res = r.json() if res.code == 200: return res.account else: session = get_user_session() if session is not None: r = requests.get('https://nid.naver.com?key=' + session) res = r.json() if res.code == 200: return res.account else: raise Exception('your account cannot be found') def main(): id = 'id' pw = 'pw' login(id, pw) if __name__ == '__main__': main() So deep indent, And this is useless Use guard clause this or make them to another function deep indent is always bad
  • 27. The quality of codes Let’s think a simple scenario. import requests def get_user_session(): # this function look inside cache layer # and user session, and return your session matched account key return 'somekey' def login(id, pw): r = requests.get('https://nid.naver.com?id=' + id, '&pw=' + pw) res = r.json() if res.code == 200: return res.account else: session = get_user_session() if session is not None: r = requests.get('https://nid.naver.com?key=' + session) res = r.json() if res.code == 200: return res.account else: raise Exception('your account cannot be found') def main(): id = 'id' pw = 'pw' login(id, pw) if __name__ == '__main__': main() Also deep indent
  • 28. The quality of codes Let’s think a simple scenario. import requests def get_user_session(): # this function look inside cache layer # and user session, and return your session matched account key return 'somekey' def login(id, pw): r = requests.get('https://nid.naver.com?id=' + id, '&pw=' + pw) res = r.json() if res.code == 200: return res.account else: session = get_user_session() if session is not None: r = requests.get('https://nid.naver.com?key=' + session) res = r.json() if res.code == 200: return res.account else: raise Exception('your account cannot be found') def main(): id = 'id' pw = 'pw' login(id, pw) if __name__ == '__main__': main() String concatenated by + operator Use interpolation or params argument of requests.get func + operator will be tough when you change param name or value for future.
  • 30. User scenario How can we learn more, this kinda trick? https://refactoring.guru/inline-class https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it https://en.wikipedia.org/wiki/Don%27t_repeat_yourself DRY rule YAGNI rule