3

I have an API wrapper class WfcAPI written in Python 3 which I want to test using PyUnit.

The setUpClass() for WfcAPI involves logging in to the external API server. The current functional test implementation has the password obfuscated with Base64 encoding, but this is far from an ideal solution for security reasons.

import unittest
import base64
from pykronos import WfcAPI

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        password = base64.b64decode("U29tZVBhc3N3b3Jk").decode("utf-8")
        self.kronos = WfcAPI("SomeUsername", password) 

I want to be able to quickly run functional tests for my API wrapper, but I also want to ensure that my username and password aren't included as part of the code.

How can I setup a Python functional test for actions which require a username and password?

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
  • can't you use, `password = input('Enter Passowrd')` – harshil9968 Nov 06 '17 at 18:29
  • @harshil9968 If I were prompting the user for a password, I would want to hide the input with [`getpass`](https://docs.python.org/3/library/getpass.html) – Stevoisiak Nov 07 '17 at 14:49
  • @StevenVascellaro, does it work for you to use `pytest` instead of `unittest`? – lmiguelvargasf Aug 22 '18 at 17:45
  • @lmiguelvargasf What would switching to pytest do? – Stevoisiak Aug 22 '18 at 17:46
  • @StevenVascellaro, it will simplify your testing since you don't need to create a class which inherits from `unittest.TestCase`, in case of a `setUp` method, you can define a fixture. Finally, in my opinion. `pytest` makes testing simpler and more enjoyable =). – lmiguelvargasf Aug 22 '18 at 17:57

1 Answers1

4

Just to clarify: if it's a unit test, you shouldn't be testing against the real external API, you should Fake its response. A unit test should only be concerned with the Subject Under Test's logic (WfcAPI) and not its sub dependences.

Now, if you do a functional test where you send real data to the API, you can protect your credentials by storing them in an .env file which won't be commited with the rest of the code.

This python library offers that functionality and gives you an example in its Readme. You'd end up with something like this:

# .env

PASSWORD=some_password
USERNAME=SomeUsername

Then in your settings.py:

PASSWORD = os.environ.get("PASSWORD")
USERNAME = os.environ.get("USERNAME")
Roberto Paredes
  • 197
  • 2
  • 13
  • I may be misunderstanding the practical difference between a unit test and a functional test. I have been using `unittest` to test data returned from the API, as I want to make sure my sent requests work properly. – Stevoisiak Nov 06 '17 at 19:26
  • This may be helpful if you want to take a look at the differences: http://www.agilenutshell.com/episodes/41-testing-pyramid But yeah, basically a unit test just tests a single function in your program. If you test against the response from an external API, it's probably better described as an integration/functional test. This is just terminology anyways. – Roberto Paredes Nov 06 '17 at 19:42
  • I've edited the question to clarify that I am writing a functional test. – Stevoisiak Feb 27 '18 at 18:31
  • Related: [*Access environment variables from Python*](https://stackoverflow.com/q/4906977/3357935) & [*How to set environment variables in PyCharm?*](https://stackoverflow.com/q/42708389/3357935) – Stevoisiak Feb 27 '18 at 18:48