Skip to content

Commit ae190d8

Browse files
committed
Add running detail and fix grammar
1 parent 106c040 commit ae190d8

File tree

3 files changed

+96
-74
lines changed

3 files changed

+96
-74
lines changed

README.md

Lines changed: 84 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@ This demo project is not cover all test cases for the HTTP operations and all RD
2222

2323
## Unit Testing Overview
2424

25-
Unit testing is the smallest test that focuses on checking that a single part of the application operates correctly. It breaks an application into the smallest, isolated, testable component called *units*, and then tests them individually. The unit is mostly a function or method call or procedure in the application source code. Developers and QA can test each unit by sending any data into that unit and see if it functions as intended.
25+
[Unit testing](https://en.wikipedia.org/wiki/Unit_testing) is the smallest test that focuses on checking that a single part of the application operates correctly. It breaks an application into the smallest, isolated, testable component called *units*, and then tests them individually. The unit is mostly a function or method call or procedure in the application source code. Developers and QA can test each unit by sending any data into that unit and see if it functions as intended.
2626

2727
A unit test helps developers to isolate what is broken in their application easier and faster than testing an entire system as a whole. It is the first level of testing done during the development process before integration testing. It is mostly done by the developers automated or manually to verify their code.
2828

29+
You can find more detail about the unit test concept from the following resources:
30+
- [Python Guide: Testing Your Code](https://docs.python-guide.org/writing/tests/) article.
31+
- [How and when to use Unit Testing properly](https://softwareengineering.stackexchange.com/questions/89064/how-and-when-to-use-unit-testing-properly) post.
32+
2933
## Introduction to Python Unittest framework
3034

3135
The [unittest](https://docs.python.org/3.9/library/unittest.html) is a Python-built unit testing framework. It supports both **test case** (the individual unit of testing) and **test runner** (a special application designed for running test cases and provides the output result).
@@ -157,11 +161,8 @@ class RDPHTTPController():
157161
self.client_secret = ''
158162
pass
159163
160-
# Send HTTP Post request to get Access Token (Password Grant and Refresh Grant) from RDP Auth Service
164+
# Send HTTP Post request to get Access Token (Password Grant and Refresh Grant) from the RDP Auth Service
161165
def rdp_authentication(self, auth_url, username, password, client_id, old_refresh_token = None):
162-
"""
163-
Send Authentication to RDP Auth service
164-
"""
165166
166167
if not auth_url or not username or not password or not client_id:
167168
raise TypeError('Received invalid (None or Empty) arguments')
@@ -232,7 +233,7 @@ class TestRDPHTTPController(unittest.TestCase):
232233
233234
def test_login_rdp_success(self):
234235
"""
235-
Test that it can logged in to the RDP Auth Service (using Mock)
236+
Test that it can log in to the RDP Auth Service
236237
"""
237238
auth_endpoint = self.base_URL + config['RDP_AUTH_URL']
238239
@@ -423,7 +424,7 @@ class TestRDPHTTPController(unittest.TestCase):
423424
@responses.activate
424425
def test_login_rdp_success(self):
425426
"""
426-
Test that it can logged in to the RDP Auth Service (using Mock)
427+
Test that it can log in to the RDP Auth Service
427428
"""
428429
auth_endpoint = self.base_URL + config['RDP_AUTH_URL']
429430
@@ -468,7 +469,7 @@ class TestRDPHTTPController(unittest.TestCase):
468469
@responses.activate
469470
def test_login_rdp_invalid(self):
470471
"""
471-
Test that it handle some invalid credentials
472+
Test that it can handle some invalid credentials
472473
"""
473474
auth_endpoint = self.base_URL + config['RDP_AUTH_URL']
474475
@@ -555,7 +556,7 @@ import json
555556
class RDPHTTPController():
556557
557558
...
558-
559+
# Send HTTP Get request to the RDP ESG Service
559560
def rdp_request_esg(self, esg_url, access_token, universe):
560561
561562
if not esg_url or not access_token or not universe:
@@ -736,7 +737,7 @@ class TestRDPHTTPController(unittest.TestCase):
736737
@responses.activate
737738
def test_request_esg_token_expire(self):
738739
"""
739-
Test that it can handle token expire requests
740+
Test that it can handle token expiration requests
740741
"""
741742
esg_endpoint = self.base_URL + config['RDP_ESG_URL']
742743
universe = 'TEST.RIC'
@@ -857,54 +858,80 @@ The test cases for this ```rdp_request_search_explore()``` method have the same
857858

858859
That’s all I have to say about unit testing the Python HTTP code with Requests and Responses libraries.
859860

860-
## Project Structure
861-
862-
## Python run app
863-
864-
865-
## Python Test
866-
867-
```
868-
python -m unittest test_http
869-
870-
python -m unittest test_rdp_http_controller
871-
872-
python -m unittest discover
873-
874-
python -m unittest test_app
875-
```
876-
877-
### Docker
878-
879-
```
880-
docker build . -t python_unittest
881-
882-
docker run -it --name python_unittest python_unittest
883-
```
861+
## <a id="prerequisite"></a>Prerequisite
862+
863+
This demo project requires the following dependencies.
864+
865+
1. RDP Access credentials.
866+
2. Python [Anaconda](https://www.anaconda.com/distribution/) or [MiniConda](https://docs.conda.io/en/latest/miniconda.html) distribution/package manager.
867+
3. [Docker Desktop/Engine](https://docs.docker.com/get-docker/) application for running the test suite with Docker.
868+
5. Internet connection.
869+
870+
Please contact your Refinitiv representative to help you to access the RDP account and services. You can find more detail regarding the RDP access credentials set up from the lease see the *Getting Started for User ID* section of the [Getting Start with Refinitiv Data Platform](https://developers.refinitiv.com/en/article-catalog/article/getting-start-with-refinitiv-data-platform) article.
871+
872+
873+
## <a id="how_to_run"></a>How to run the example test suite
874+
875+
The first step is to unzip or download the example project folder into a directory of your choice, then set up Python or Docker environments based on your preference.
876+
877+
### <a id="python_example_run"></a>Run example test suite in a console
878+
879+
1. Open Anaconda Prompt and go to the project's folder.
880+
2. Run the following command in the Anaconda Prompt application to create a Conda environment named *http_unittest* for the project.
881+
```
882+
(base) $>conda create --name http_unittest python=3.9
883+
```
884+
3. Once the environment is created, activate a Conda *http_unittest* environment with this command in Anaconda Prompt.
885+
```
886+
(base) $>conda activate http_unittest
887+
```
888+
4. Run the following command to the dependencies in the *http_unittest* environment
889+
```
890+
(http_unittest) $>pip install -r requirements.txt
891+
```
892+
5. Once the dependencies installation process success, Go to the project's *tests* folder, then run the following command to run the ```test_rdp_http_controller.py``` test suite.
893+
```
894+
(http_unittest) $>tests\python -m unittest test_rdp_http_controller
895+
```
896+
6. To run all test suites (```test_rdp_http_controller.py`` and ```test_app.py``` files), run the following command in the project's *tests* folder.
897+
```
898+
(http_unittest) $>tests\python -m unittest discover
899+
```
900+
901+
### <a id="python_example_run"></a>Run example test suite in Docker
902+
903+
1. Start Docker
904+
2. Open a console, then go to the *project root* and run the following command to build a Docker image.
905+
```
906+
$> docker build . -t python_unittest
907+
```
908+
3. Run a Docker container with the following command:
909+
```
910+
$> docker run -it --name python_unittest python_unittest
911+
```
912+
4. To stop and delete a Docker container, press ``` Ctrl+C``` (or run ```docker stop python_unittest```) then run the following command:
913+
```
914+
$> docker rm python_unittest
915+
```
884916
885917
## <a id="references"></a>References
886918
887-
https://realpython.com/python-testing/
888-
https://realpython.com/testing-third-party-apis-with-mocks/
889-
890-
https://pymotw.com/2/unittest/
891-
892-
https://auth0.com/blog/mocking-api-calls-in-python/
893-
894-
https://www.digitalocean.com/community/tutorials/how-to-use-unittest-to-write-a-test-case-for-a-function-in-python
895-
896-
https://stackoverflow.com/questions/62938765/writing-a-unit-test-for-python-rest-api-function
897-
898-
899-
https://docs.python.org/3/library/unittest.html
900-
901-
https://web.archive.org/web/20150315073817/http://www.xprogramming.com/testfram.htm
902-
903-
https://betterprogramming.pub/13-tips-for-writing-useful-unit-tests-ca20706b5368
904-
905-
https://docs.python-guide.org/writing/tests/
906-
907-
https://softwareengineering.stackexchange.com/questions/89064/how-and-when-to-use-unit-testing-properly
908-
909-
https://en.wikipedia.org/wiki/Mock_object
919+
For further details, please check out the following resources:
920+
* [Refinitiv Data Platform APIs page](https://developers.refinitiv.com/en/api-catalog/refinitiv-data-platform/refinitiv-data-platform-apis) on the [Refinitiv Developer Community](https://developers.refinitiv.com/) website.
921+
* [Refinitiv Data Platform APIs Playground page](https://api.refinitiv.com).
922+
* [Refinitiv Data Platform APIs: Introduction to the Request-Response API](https://developers.refinitiv.com/en/api-catalog/refinitiv-data-platform/refinitiv-data-platform-apis/tutorials#introduction-to-the-request-response-api).
923+
* [Refinitiv Data Platform APIs: Authorization - All about tokens](https://developers.refinitiv.com/en/api-catalog/refinitiv-data-platform/refinitiv-data-platform-apis/tutorials#authorization-all-about-tokens).
924+
* [Limitations and Guidelines for the RDP Authentication Service](https://developers.refinitiv.com/en/article-catalog/article/limitations-and-guidelines-for-the-rdp-authentication-service) article.
925+
* [Getting Started with Refinitiv Data Platform](https://developers.refinitiv.com/en/article-catalog/article/getting-start-with-refinitiv-data-platform) article.
926+
* [Python unittest framework official page](https://docs.python.org/3/library/unittest.html).
927+
* [Responses library page](https://github.com/getsentry/responses).
928+
* [Python Guide: Testing Your Code](https://docs.python-guide.org/writing/tests/) article.
929+
* [Getting Started With Testing in Python](https://realpython.com/python-testing/) article.
930+
* [Mocking External APIs in Python](https://realpython.com/testing-third-party-apis-with-mocks/) article.
931+
* [How To Use unittest to Write a Test Case for a Function in Python](https://www.digitalocean.com/community/tutorials/how-to-use-unittest-to-write-a-test-case-for-a-function-in-python) article.
932+
* [Mocking API calls in Python](https://auth0.com/blog/mocking-api-calls-in-python/) article.
933+
* [How and when to use Unit Testing properly](https://softwareengineering.stackexchange.com/questions/89064/how-and-when-to-use-unit-testing-properly) post.
934+
* [13 Tips for Writing Useful Unit Tests](https://betterprogramming.pub/13-tips-for-writing-useful-unit-tests-ca20706b5368) blog post.
935+
936+
For any questions related to Refinitiv Data Platform APIs, please use the [RDP APIs Forum](https://community.developers.refinitiv.com/spaces/231/index.html) on the [Developers Community Q&A page](https://community.developers.refinitiv.com/).
910937

rdp_controller/rdp_http_controller.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@ def __init__(self):
99
self.client_secret = ''
1010
pass
1111

12-
# Send HTTP Post request to get Access Token (Password Grant and Refresh Grant) from RDP Auth Service
12+
# Send HTTP Post request to get Access Token (Password Grant and Refresh Grant) from the RDP Auth Service
1313
def rdp_authentication(self, auth_url, username, password, client_id, old_refresh_token = None):
14-
"""
15-
Send Authentication to RDP Auth service
16-
"""
1714

1815
if not auth_url or not username or not password or not client_id:
1916
raise TypeError('Received invalid (None or Empty) arguments')
@@ -49,6 +46,7 @@ def rdp_authentication(self, auth_url, username, password, client_id, old_refres
4946

5047
return access_token, refresh_token, expires_in
5148

49+
# Send HTTP Get request to the RDP ESG Service
5250
def rdp_request_esg(self, esg_url, access_token, universe):
5351

5452
if not esg_url or not access_token or not universe:
@@ -71,6 +69,7 @@ def rdp_request_esg(self, esg_url, access_token, universe):
7169

7270
return response.json()
7371

72+
# Send HTTP Post request to the RDP Search Explore Service
7473
def rdp_request_search_explore(self, search_url, access_token, payload):
7574

7675
if not search_url or not access_token or not payload:

tests/test_rdp_http_controller.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,22 @@
2424

2525
class TestRDPHTTPController(unittest.TestCase):
2626

27-
# A class method called before tests in an individual class are run
27+
# A class method called before all tests in an individual class are run
2828
@classmethod
2929
def setUpClass(cls):
3030
# Create an app object for the RDPHTTPController class
3131
cls.app = rdp_http_controller.RDPHTTPController()
3232
# Getting the RDP APIs https://api.refinitiv.com base URL.
3333
cls.base_URL = config['RDP_BASE_URL']
34-
# Loading Mock RDP Auth Token success Response JSON
34+
# Loading Mock the RDP Auth Token success Response JSON
3535
with open('./fixtures/rdp_test_auth_fixture.json', 'r') as auth_fixture_input:
3636
cls.mock_valid_auth_json = json.loads(auth_fixture_input.read())
3737

38-
# Mock RDP Auth Token Expire Response JSON
38+
# Mock the RDP Auth Token Expire Response JSON
3939
with open('./fixtures/rdp_test_token_expire_fixture.json', 'r') as auth_expire_fixture_input:
4040
cls.mock_token_expire_json = json.loads(auth_expire_fixture_input.read())
4141

42-
# Mock RDP Search Explore request message object
42+
# Mock the RDP Search Explore request message object
4343
cls.search_explore_payload = {
4444
'View': 'Entities',
4545
'Filter': '',
@@ -50,7 +50,7 @@ def setUpClass(cls):
5050
@responses.activate
5151
def test_login_rdp_success(self):
5252
"""
53-
Test that it can logged in to the RDP Auth Service (using Mock)
53+
Test that it can log in to the RDP Auth Service
5454
"""
5555
auth_endpoint = self.base_URL + config['RDP_AUTH_URL']
5656

@@ -84,10 +84,6 @@ def test_login_rdp_refreshtoken(self):
8484
"""
8585
auth_endpoint = self.base_URL + config['RDP_AUTH_URL']
8686

87-
#Create new access_token
88-
# alphabet = string.ascii_letters + string.digits
89-
# self.mock_valid_auth_json['access_token'] = ''.join(secrets.choice(alphabet) for i in range(250))
90-
9187
self.mock_valid_auth_json['access_token'] = 'new_access_token_mock1mock2mock3mock4mock5mock6'
9288

9389
mock_rdp_auth = responses.Response(
@@ -115,7 +111,7 @@ def test_login_rdp_refreshtoken(self):
115111
@responses.activate
116112
def test_login_rdp_invalid(self):
117113
"""
118-
Test that it handle some invalid credentials
114+
Test that it can handle some invalid credentials
119115
"""
120116
auth_endpoint = self.base_URL + config['RDP_AUTH_URL']
121117

@@ -208,7 +204,7 @@ def test_request_esg(self):
208204
@responses.activate
209205
def test_request_esg_token_expire(self):
210206
"""
211-
Test that it can handle token expire requests
207+
Test that it can handle token expiration requests
212208
"""
213209
esg_endpoint = self.base_URL + config['RDP_ESG_URL']
214210
universe = 'TEST.RIC'
@@ -278,7 +274,7 @@ def test_request_esg_none_empty(self):
278274
@responses.activate
279275
def test_request_search_explore(self):
280276
"""
281-
Test that it can get RIC's meta data via RDP Search Explore service
277+
Test that it can get RIC's metadata via the RDP Search Explore Service
282278
"""
283279
search_endpoint = self.base_URL + config['RDP_SEARCH_EXPLORE_URL']
284280

@@ -308,7 +304,7 @@ def test_request_search_explore(self):
308304
@responses.activate
309305
def test_request_search_explore_token_expire(self):
310306
"""
311-
Test that it can handle token expire requests
307+
Test that it can handle token expiration requests
312308
"""
313309
search_endpoint = self.base_URL + config['RDP_SEARCH_EXPLORE_URL']
314310

0 commit comments

Comments
 (0)