This document provides an overview and examples of using the Pytest testing framework. Some key points:
- Pytest allows writing tests in plain Python functions, with test discovery and running. It supports fixtures for dependency injection and parametrizing tests.
- Basic usage involves writing test functions prefixed with "test_" and running pytest to discover and execute them. Fixtures provide a way to inject dependencies into tests.
- Fixtures can be defined and applied at various scopes (function, class, module). They support dependency injection, parameterization, setup/teardown functionality.
- Pytest offers many options for running tests selectively, debugging failures, tracing execution, and extending functionality through plugins. It aims to make
본 장표는 인프콘 2022 / 코틀린 멀티플랫폼, 미지와의 조우 세션에 대한 강연 자료입니다.
코틀린은 멀티플랫폼을 지원하는 언어로 Server-side와 Android뿐만이 아니라 JavaScript 엔진이 있는 브라우저나 Node.js도 지원하며, Native 등 다양한 플랫폼에서 쓸 수 있습니다. 이를 이용해 코틀린 코드를 공유하는 단일 코드베이스로 모바일부터 웹과 데스크톱, 서버에 이르기까지 다중 플랫폼 애플리케이션을 작성할 수 있습니다.
본 핸즈온 세션을 통해 코틀린 멀티플랫폼과 함께 리액트, 스프링부트로 웹 애플리케이션의 프론트엔드부터 백엔드까지 직접 개발하며 친해져 보는 시간을 가져보세요. 참가자는 코틀린 멀티플랫폼 프로젝트를 이해하고, 더 나아가 프론트엔드와 백엔드 간의 공유 로직 작성, Kotlin/JS 기반 리액트 및 스프링 웹 프로그래밍을 경험할 수 있습니다.
https://github.com/arawn/building-fullstack-webapp-with-kotlin-multiplatform
https://infcon.day/speaker/박용권-김지헌-코틀린-멀티플랫폼/
The document discusses analyzing crashes using WinDbg. It provides tips on reconstructing crashed call stacks and investigating what thread or lock is causing a hang. The debugging commands discussed include !analyze, !locks, .cxr, kb to find the crashing function and stuck thread.
A talk describing our experiences building monorepo at Pinterest.
This talk was presented at Mobile Summit'18 held at CapitalOne in SF on May 22, 2018.
배민찬(https://www.baeminchan.com) 서비스의 백엔드 시스템 중 일부가 지난 1년간 어떤 고민과 아이디어, 결과물을 만들어냈는지 공유하려고 합니다. 발표 중 언급되는 용어나 도구에 대해 일반적인 정의나 간단한 설명은 언급되나 자세히 다루지 않습니다. 사용된 도구들로 어떻게 이벤트 기반 분산 시스템을 만들었는지에 대한 이야기가 중심입니다.
Deep dive into Coroutines on JVM @ KotlinConf 2017Roman Elizarov
Deep dive into Coroutines on JVM, presented at KotlinConf 2017; video is available https://www.youtube.com/watch?v=YrrUCSi72E8&t=5s
본 장표는 인프콘 2022 / 코틀린 멀티플랫폼, 미지와의 조우 세션에 대한 강연 자료입니다.
코틀린은 멀티플랫폼을 지원하는 언어로 Server-side와 Android뿐만이 아니라 JavaScript 엔진이 있는 브라우저나 Node.js도 지원하며, Native 등 다양한 플랫폼에서 쓸 수 있습니다. 이를 이용해 코틀린 코드를 공유하는 단일 코드베이스로 모바일부터 웹과 데스크톱, 서버에 이르기까지 다중 플랫폼 애플리케이션을 작성할 수 있습니다.
본 핸즈온 세션을 통해 코틀린 멀티플랫폼과 함께 리액트, 스프링부트로 웹 애플리케이션의 프론트엔드부터 백엔드까지 직접 개발하며 친해져 보는 시간을 가져보세요. 참가자는 코틀린 멀티플랫폼 프로젝트를 이해하고, 더 나아가 프론트엔드와 백엔드 간의 공유 로직 작성, Kotlin/JS 기반 리액트 및 스프링 웹 프로그래밍을 경험할 수 있습니다.
https://github.com/arawn/building-fullstack-webapp-with-kotlin-multiplatform
https://infcon.day/speaker/박용권-김지헌-코틀린-멀티플랫폼/
The document discusses analyzing crashes using WinDbg. It provides tips on reconstructing crashed call stacks and investigating what thread or lock is causing a hang. The debugging commands discussed include !analyze, !locks, .cxr, kb to find the crashing function and stuck thread.
A talk describing our experiences building monorepo at Pinterest.
This talk was presented at Mobile Summit'18 held at CapitalOne in SF on May 22, 2018.
배민찬(https://www.baeminchan.com) 서비스의 백엔드 시스템 중 일부가 지난 1년간 어떤 고민과 아이디어, 결과물을 만들어냈는지 공유하려고 합니다. 발표 중 언급되는 용어나 도구에 대해 일반적인 정의나 간단한 설명은 언급되나 자세히 다루지 않습니다. 사용된 도구들로 어떻게 이벤트 기반 분산 시스템을 만들었는지에 대한 이야기가 중심입니다.
Deep dive into Coroutines on JVM @ KotlinConf 2017Roman Elizarov
Deep dive into Coroutines on JVM, presented at KotlinConf 2017; video is available https://www.youtube.com/watch?v=YrrUCSi72E8&t=5s
넥슨코리아 사내 발표자료로 왓 스튜디오에서 파이썬으로 《야생의 땅: 듀랑고》 서버를 비롯한 여러가지 도구를 만든 경험을 공유합니다.
- 게임서버와 각종 툴, 테스트/빌드/배포 시스템을 만들 때 사용한 재료
- 파이썬 코드 품질 개선, 디버깅, 프로파일링, 최적화
- 파이썬 오픈소스 생태계와 왓 스튜디오가 하는 오픈소스 활동
Art(h)ur discusses Ajax and its use in web development frameworks like Django. While Ajax is widely adopted, concerns about its implementation include file size, performance, generated markup, accessibility, and SEO. Django is praised for not shipping with a single Ajax library, allowing developers flexibility, though this is sometimes cited as a weakness. Loose coupling, hooks, and a library-agnostic approach can help address issues with Ajax implementations.
The document discusses various Python standard library modules. It introduces string formatting methods like format() and regular expressions. It also covers datetime and calendar modules for working with dates and times, collections for specialized container datatypes, and numeric and math modules. Functions like map(), filter() and modules like functools, itertools, os, sys are also mentioned. The document provides examples of using these modules.
This document discusses the importance of testing in Django and provides examples of how to write tests. It describes how the Pinax project added tests after users were able to incorrectly edit ticket statuses. It recommends writing unit tests using the Django testing framework and provides a pattern for organizing and writing tests, including setting up test data and individual test methods. The document emphasizes that code without tests is "broken by design" and that writing tests improves code quality and avoids embarrassment.
Automating Django Functional Tests Using Selenium on CloudJonghyun Park
This document discusses automating Django functional tests using Selenium on AWS EC2. It begins with an overview of testing login functionality on Django using Selenium. It then covers running Selenium tests on the AWS cloud to allow automated testing. Tips are provided for writing efficient functional tests, including using explicit waits, page object models, and test organization techniques. The document aims to help Python beginner-intermediates implement automated functional testing.
Baekjoon Online Judge(https://www.acmicpc.net) 에서 채점할 때 사용하는 샌드박스에 대한 간단한 설명을 담고 있습니다.
2012년 10월에 작성한 파일이라서 현재 사용하는 방식과는 많은 차이가 있고, 기초적인 수준의 샌드박싱을 다룹니다.
A creative copywriter with years of experience, excellent English and Spanish is looking for a job. Check out my portfolio - maybe I'm the one to fit your company in a best way!
More and more web projects require interfacing with the backend using a REST-ful interface. In this presentation we'll discuss Django-REST-Framework's features and walk through how to integrate it into your next project!
Advanced Python Testing Techniques (Pycon KR 2019) [Korean Ver.]Jaeman An
• 기본적인 테스트 구현하기
• Sure를 이용하여 더 직관적으로 테스트 코드를 구현하기
• Behavior Driven Development (BDD) 를 이용하여 더 재미있게 테스트 코드를 구현하기 • HTTP Mocking과 monkey patching으로 독립적인 테스트 코드 구현하기
• Randomized testing을 이용하여 온전한 테스트 코드 구현하기
• Benchmark testing을 이용하여 로직 시간 측정하기
• 간단한 pytest plugin 만들기
17. PortfolioPortfolio
# portfolio.py from http://nedbatchelder.com/text/st.html#7
class Portfolio(object):
"""간단한 주식 포트폴리오"""
def __init__(self):
# stocks is a list of lists:
# [[name, shares, price], ...]
self.stocks = []
def buy(self, name, shares, price):
"""name 주식을 shares 만큼 주당 price 에 삽니다"""
self.stocks.append([name, shares, price])
def cost(self):
"""이 포트폴리오의 총액은 얼마일까요?"""
amt = 0.0
for name, shares, price in self.stocks:
amt += shares * price
return amt
18. 첫번째첫번째 테스트테스트 -- 쉘쉘
Python 3.4.0 (default, Jun 19 2015, 14:20:21)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more informati
>>> from portfolio import Portfolio
>>> p = Portfolio()
>>> print(p.cost())
0.0
>>> p.buy('Google', 100, 176.48)
>>> p.cost()
17648.0
>>> p.buy('Yahoo', 100, 36.15)
>>> p.cost()
21263.0
Good
테스트 했어요!
Bad
다시 테스트 하려면?
직접 입력
그래서 잘 된건가?
19. 두번째두번째 테스트테스트 -- 기대값기대값
from portfolio import Portfolio
p = Portfolio()
print("Empty portfolio cost: %s, should be 0.0" % p.cost())
p.buy('Google', 100, 176.48)
print("With 100 Google @ 176.48: %s, should be 17648.0" % p.cost())
p.buy('Yahoo', 100, 36.15)
print("With 100 Yahoo @ 36.15: %s, should be 21263.0" % p.cost())
Good
테스트 했음
다시 테스트 할 수 있음
잘 된건지 확인 가능
Bad
눈으로 확인 해야 함
Empty portfolio cost: 0.0, should be 0.0
With 100 Google @ 176.48: 17648.0, should be 17648.0
With 100 Yahoo @ 36.15: 21263.0, should be 21263.0
20. 세번째세번째 테스트테스트 -- 결과결과 확인확인
from portfolio import Portfolio
p = Portfolio()
print("Empty portfolio cost: %s, should be 0.0" % p.cost())
p.buy('Google', 100, 176.48)
assert p.cost() == 17649.0 # Failed
print("With 100 Google @ 176.48: %s, should be 17648.0" % p.cost())
p.buy('Yahoo', 100, 36.15)
assert p.cost() == 21263.0
print("With 100 Yahoo @ 36.15: %s, should be 21263.0" % p.cost())
Good
다시 테스트 할 수 있음
잘 된건지 자동으로 확인 가
능
Bad
왜 틀렸는지 알기 힘듬
두번째 테스트가 실행 되지
않음
Empty portfolio cost: 0.0, should be 0.0
Traceback (most recent call last):
File "portfolio_test2.py", line 6, in <module>
assert p.cost() == 17649.0 # Failed
AssertionError
29. First UnittestFirst Unittest
# portfolio_test3.py
import unittest
from portfolio import Portfolio
class PortfolioTest(unittest.TestCase):
def test_google(self):
p = Portfolio()
p.buy("Google", 100, 176.48)
self.assertEqual(17648.0, p.cost())
if __name__ == '__main__':
unittest.main()
$ python portfolio_test3.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
31. 테스트테스트 추가추가
# portfolio_test4.py
import unittest
from portfolio import Portfolio
class PortfolioTestCase(unittest.TestCase):
def test_google(self):
p = Portfolio()
p.buy("Goole", 100, 176.48)
self.assertEqual(17648.0, p.cost())
def test_google_yahoo(self):
p = Portfolio()
p.buy("Google", 100, 176.48)
p.buy("Yahoo", 100, 36.15)
self.assertEqual(21264.0, p.cost()) # 21263.0
if __name__ == '__main__':
unittest.main()
32. UnittestUnittest 실패실패
$ python portfolio_test4.py
.F
======================================================================
FAIL: test_google_yahoo (__main__.PortfolioTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "portfolio_test4.py", line 15, in test_google_yahoo
self.assertEqual(21264.0, p.cost())
AssertionError: 21264.0 != 21263.0
----------------------------------------------------------------------
Ran 2 tests in 0.005s
FAILED (failures=1)
Good
테스트 실패가 다른 테스트에 영향을 미치지 않음
실패한 위치와 이유를 알 수 있음
34. TestTest 고르기고르기
$ python portfolio_test4.py PortfolioTestCase.test_google_yahoo
F
======================================================================
FAIL: test_google_yahoo (__main__.PortfolioTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "portfolio_test4.py", line 15, in test_google_yahoo
self.assertEqual(21264.0, p.cost())
AssertionError: 21264.0 != 21263.0
----------------------------------------------------------------------
Ran 1 test in 0.005s
FAILED (failures=1)
Good
원하는 테스트만 빠르게 실행 해 볼 수 있음
출력이 간단해짐
36. 테스트테스트 한꺼번에한꺼번에 실행하기실행하기
$ python -m unittest discover --help
Usage: python -m unittest discover [options]
Options:
,,,
-s START, --start-directory=START
Directory to start discovery ('.' default)
-p PATTERN, --pattern=PATTERN
Pattern to match tests ('test*.py' default)
-t TOP, --top-level-directory=TOP
Top level directory of project (defaults to start
directory)
$ python -m unittest discover
----------------------------------------------------------------------
Ran 15 tests in 0.130s
OK
Good
복수개의 파일을 한꺼번에 테스트를 실행 할 수있음
38. Portfolio -Portfolio - 타입타입 확인확인
class Portfolio(object):
"""간단한 주식 포트폴리오"""
def __init__(self):
# stocks is a list of lists:
# [[name, shares, price], ...]
self.stocks = []
def buy(self, name, shares, price):
"""name 주식을 shares 만큼 주당 price 에 삽니다"""
self.stocks.append([name, shares, price])
if not isinstance(shares, int):
raise Exception("shares must be an integer")
def cost(self):
"""이 포트폴리오의 총액은 얼마일까요?"""
amt = 0.0
for name, shares, price in self.stocks:
amt += shares * price
return amt
39. ExceptionException 을을 발생시키는발생시키는 테스트테스트
import unittest
from portfolio import Portfolio
class PortfolioTestCase(unittest.TestCase):
def test_google(self):
p = Portfolio()
p.buy("Goole", "many", 176.48)
self.assertEqual(17648.0, p.cost())
if __name__ == '__main__':
unittest.main()
$ python ./portfolio_test5.py
E
======================================================================
ERROR: test_google (__main__.PortfolioTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "./portfolio_test5.py", line 8, in test_google
p.buy("Goole", "many", 176.48)
File "/home/leclipse/git/pycon-testing/unit_test/portfolio.py", line 14, in buy
raise Exception("shares must be an integer")
Exception: shares must be an integer
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
40. ExceptionException 을을 테스트테스트
import unittest
from portfolio import Portfolio
class PortfolioTestCase(unittest.TestCase):
def test_google(self):
p = Portfolio()
with self.assertRaises(Exception) as context:
p.buy("Goole", "many", 176.48)
self.assertTrue("shares must be an integer", context.exception)
if __name__ == '__main__':
unittest.main()
$ python ./portfolio_test6.py
.
----------------------------------------------------------------------
Ran 1 test in 0.004s
OK
48. 반복되는반복되는 테스트테스트 실행하기실행하기
import unittest
class NumberTest(unittest.TestCase):
def test_even(self):
for i in range(0, 6):
self.assertEqual(i % 2, 0)
def test_even_with_subtest(self):
for i in range(0, 6):
with self.subTest(i=i):
self.assertEqual(i % 2, 0)
unittest.main()
0 부터 5 까지 짝수인지를 테스트 합니다.
49. SubtestSubtest 실행실행 결과결과
$ python ./subtest.py
F
======================================================================
FAIL: test_even (__main__.NumberTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "./subtest.py", line 7, in test_even
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even_with_subtest (__main__.NumberTest) (i=1)
----------------------------------------------------------------------
Traceback (most recent call last):
File "./subtest.py", line 12, in test_even_with_subtest
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even_with_subtest (__main__.NumberTest) (i=3)
----------------------------------------------------------------------
Traceback (most recent call last):
File "./subtest.py", line 12, in test_even_with_subtest
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
======================================================================
FAIL: test_even_with_subtest (__main__.NumberTest) (i=5)
----------------------------------------------------------------------
Traceback (most recent call last):
File "./subtest.py", line 12, in test_even_with_subtest
self.assertEqual(i % 2, 0)
AssertionError: 1 != 0
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=4)
Good
중단 되지 않고 모두 테
스트
변경 되는 값을 확인 할
수 있다.
python 3.4 에 추가 되었음
58. unittest.mockunittest.mock
파이썬 표준 라이브러리 (3.3 부터)
이전 버젼은 pip install mock
python object 들을 동적으로 대체하고
사용 결과를 확인 하기 위한 다양한 기능들을 제공
의존성이 있는것들을 실제로 실행시키지 말고 호출 여
부, 인터페이스만 확인 하자
59. Monkey PatchMonkey Patch
>>> class Class():
... def add(self, x, y):
... return x + y
...
>>> inst = Class()
>>> def not_exactly_add(self, x, y):
... return x * y
...
>>> Class.add = not_exactly_add
>>> inst.add(3, 3)
9
런타임에 클래스, 함수등을 변경하는 것
60. mockmock 사용사용 예예
>>> from unittest.mock import MagicMock
>>> thing = ProductionClass()
>>> thing.method = MagicMock(return_value=3)
>>> thing.method(3, 4, 5, key='value')
3
>>> thing.method.assert_called_with(3, 4, 5, key='value')
thing.method 가 monkey patch 되었음
이를 테스트에 어떻게 활용 할까?
61. test rmtest rm
# Rm.py
import os
def rm(filename):
os.remove(filename)
# test_rm.py
from Rm import rm
class RmTestCase(unittest.TestCase):
tmpfilepath = os.path.join(tempfile.gettempdir(), 'temp-testfile')
def setUp(self):
with open(self.tmpfilepath, 'w') as f:
f.write('Delete me!')
def tearDown(self):
if os.path.isfile(self.tmpfilepath):
os.remove(self.tmpfilepath)
def test_rm(self):
rm(self.tmpfilepath)
self.assertFalse(os.path.isfile(self.tmpfilepath), 'Failed to remove the file')
62. 첫번째첫번째 Mock testMock test
import os.path
import tempfile
import unittest
from unittest import mock
from Rm import rm
class RmTestCase(unittest.TestCase):
@mock.patch('Rm.os')
def test_rm(self, mock_os):
rm('/tmp/tmpfile')
mock_os.remove.assert_called_with('/tmp/tmpfile')
if __name__ == '__main__':
unittest.main()
Good
setUp, tearDown 이 없어졌음
실제로 os.remove 이 호출되지 않았음
os.remove 가 호출되었는지는 확인 했음
test_rm
Rm.rm
os.remove
mock_os.
remove
63. 어떻게어떻게 된걸까된걸까??
# Rm.py
import os
def rm(filename):
print(os.remove)
os.remove(filename)
$ python ./test_rm.py
<built-in function remove>
.
----------------------------------------------------------------------
Ran 1 test in 0.007s
OK
$ python ./mock_rm.py
<MagicMock name='os.remove' id='139901238735592'>
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
64. MockMock 대상이대상이 되는되는 것것
시간이 오래 걸리는 것
값이 변하는 것
상태가 유지 되는 것
(다른 테스트에 영향을 주는 것)
시스템 콜
네트워크로 연결된 것
준비하기 복잡한 것
65. Realworld exampleRealworld example
class SimpleFacebook(object):
def __init__(self, oauth_token):
self.graph = facebook.GraphAPI(oauth_token)
def post_message(self, message):
self.graph.put_object('me', 'feed', message=message)
class SimpleFacebookTestCase(unittest.TestCase):
@mock.patch.object(facebook.GraphAPI, 'put_object', autospect=True)
def test_post_message(self, mock_put_object):
sf = SimpleFacebook('fake oauth token')
sf.post_message('Hello World!')
mock_put_object.assert_called_with('me', 'feed', message='Hello World!')
facebook 이 다운되어도 내 테스트는 실패 하지 않는다.
66. Mock -Mock - 조건조건 확인확인
# 24시간이 지난 경우에만 삭제 합니다.
def rm(filename):
file_modified = datetime.datetime.fromtimestamp(os.path.getmtime(filename
if datetime.datetime.now() - file_modified > datetime.timedelta(hours=24)
os.remove(filename)
class RmTestCase(unittest.TestCase):
@mock.patch('__main__.os')
def test_rm(self, mock_os):
mock_os.path.getmtime.return_value = time.time()
rm('/tmp/tmpfile')
self.assertFalse(mock_os.remove.called)
mock_os.path.getmtime.return_value = time.time() - 86400*2
rm('/tmp/tmpfile')
mock_os.remove.assert_called_with('/tmp/tmpfile')
보통 분기를 따라가면서 테스트 하기는 쉽지 않음
67. MockMock 예외예외
# Rm.py
class MyError(Exception):
pass
def rm(filename):
try:
os.remove(filename)
except FileNotFoundError:
raise MyError
class RmTestCase(unittest.TestCase):
@mock.patch.object(os, 'remove', side_effect=FileNotFoundError)
def test_rm_without_file(self, mock_remove):
with self.assertRaises(MyError) as context:
rm('not_exist_file')
Exception 이 발생되는 경우를 만들지 않아도 됨
69. Integration TestIntegration Test
테스트 환경이 동작하지 않아요.
프로덕션 환경이랑 테스트 환경이 다른 것 같은데요?
저 지금 테스트 환경에 배포 해도 돼요?
제가 지금 테스트 하고 있으니, 다른 분은 나중에 테스트 해주세
요.
다른 모듈,서비스 등을 붙여서 그 관계에서의
문제점을 확인하는 과정
77. docker-compose updocker-compose up
Good
Localhost 에서 모든 테스트가 가능
Host 에 영향 없음
CI 에서도 실행 가능
$ docker-compose up
redis_1 | 1:M 28 Aug 06:05:53.613 # Server started, Redis version 3.0.3
redis_1 | 1:M 28 Aug 06:05:53.613 # WARNING overcommit_memory is set to 0! Background save may fai
redis_1 | 1:M 28 Aug 06:05:53.613 # WARNING you have Transparent Huge Pages (THP) support enabled
redis_1 | 1:M 28 Aug 06:05:53.613 # WARNING: The TCP backlog setting of 511 cannot be enforced bec
redis_1 | 1:M 28 Aug 06:05:53.614 * DB loaded from disk: 0.000 seconds
redis_1 | 1:M 28 Aug 06:05:53.614 * The server is now ready to accept connections on port 6379
client_1 | .
client_1 | ----------------------------------------------------------------------
client_1 | Ran 1 test in 1.003s
client_1 |
client_1 | OK
integrationtest_client_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Stopping integrationtest_redis_1... done
$
82. Test Pycon 2015Test Pycon 2015
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class PyconUserTestCase(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def test_log_in_pycon_2015(self):
driver = self.driver
driver.get("http://www.pycon.kr/2015/login")
# US1 : 사용자는 Pycon Korea 2015 페이지 제목을 볼 수 있습니다.
self.assertIn("PyCon Korea 2015", driver.title)
# US2 : 사용자는 로그인을 할 수 있습니다.
# 로그인 하면 "One-time login token ..." 메시지를 볼 수 있습니다.
elem = driver.find_element_by_id("id_email")
elem.send_keys("[email protected]")
elem.send_keys(Keys.RETURN)
self.assertIn("One-time login token url was sent to your mail",
driver.page_source)
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main(warnings='ignore')