[PYTHON] Testé avec boto3 + mock

introduction

J'ai écrit du code qui fonctionne sur AWS S3 en utilisant boto3. J'ai décidé d'écrire un code de test et j'ai décidé de le créer en utilisant mock et unittest.

Préparation

Tout d'abord, préparez l'environnement. Créez un dossier approprié et créez un environnement à l'aide de virtualenv. Cette fois, il est supposé qu'il sera installé sur AWS Lambda. Après cela, pip boto3 et mock.

Préparation environnementale

$ mkdir s3operation
$ cd s3operation
$ virtualenv .
$ source bin/activate
$ pip install boto3
$ pip install moto

Exemple de classe à utiliser sur S3

$ pwd
~/s3operation/
$ vi s3access.py

s3access.py


# -*- coding:utf-8 -*-
import boto3
import os.path

class S3Access:
    s3 = None
    def __init__(self):
        self.s3 = boto3.client('s3')
    
    def upload(self, bucketname, uploadfilepath, s3folder):
        """
Télécharger vers S3
        @param nom du compartiment S3 nom du compartiment
        @param uploadfilepath Chemin du fichier à télécharger
        @param s3folder Chemin du dossier sous le compartiment S3 (nom de fichier non inclus)
        """
        basefilename = os.path.basename(uploadfilepath)
        s3filepath   = s3folder + '/' + basefilename
        self.s3.upload_file(uploadfilepath, bucketname, s3filepath)

Code de test

Cette fois, j'en ai fait un programme de téléchargement uniquement. Maintenant écrivons le code de test. Tout d'abord, la configuration de l'environnement.

Composition environnementale

Il s'agit de la structure des fichiers / dossiers. Je voulais créer uniquement le code de test dans un autre dossier (dossier de test cette fois), il ressemble donc à ce qui suit.

~/s3operation/
    s3access.py
    test/
        testfile.txt
        tests3access.py

Code de test

Le code de test ressemble à ceci:

tests3access.py


# -*- coding:utf-8 -*-
import boto3
import unittest

from moto import mock_s3

import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../')
from s3access import S3Access

class TestS3Access(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    @mock_s3
    def test_s3_upload(self):
        #Initialisation
        bucketname = 'testbucket001'
        prefix     = 'firstfolder'

        ##La préparation du test(Bucket, création d'objets)
        s3test = boto3.client('s3')
        s3test.create_bucket(Bucket=bucketname)
        s3test.put_object(Bucket=bucketname, Key=prefix)

        #Génération d'objets à tester
        s3 = S3Access()
        #Exécution de la méthode cible
        s3.upload('./test.md', bucketname, prefix)
        
        #Confirmation du résultat de l'exécution
        ##Lire les informations téléchargées depuis S3
        keyname  = prefix + '/test.md'
        response = s3test.get_object(Bucket=bucketname, Key=keyname)
        body     = response['Body'].read().decode('utf-8').encode('utf-8')
        ##Chargez le fichier téléchargé
        fp       = open(filename, 'r')
        readStr  = fp.read()
        fp.close
        ##Vérifiez le résultat
        assert body2 == readStr

Essai

Maintenant que nous avons le code de test, exécutons le test.

$ pwd
~/s3operation/test/
$ python -m unittest discover ./
.
----------------------------------------------------------------------
Ran 1 tests in 0.472s

OK

Un test a maintenant été exécuté et a réussi.

Si ça échoue

S'il y a une erreur dans un programme, cela ressemblera à ceci: Tout ce que vous avez à faire est d'analyser les informations d'erreur et de les corriger.

python -m unittest discover ./
E
======================================================================
ERROR: test_s3_upload (tests3access.TestS3Access)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "~/s3operation/lib/python2.7/site-packages/moto/core/models.py", line 70, in wrapper
    result = func(*args, **kwargs)
  File "~/s3operation/test/tests3access.py", line 43, in test_s3_upload
    response = s3test.get_object(Bucket=bucketname, Key=keyname)
  File "~/s3operation/lib/python2.7/site-packages/botocore/client.py", line 310, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "~/s3operation/lib/python2.7/site-packages/botocore/client.py", line 599, in _make_api_call
    raise error_class(parsed_response, operation_name)
NoSuchKey: An error occurred (NoSuchKey) when calling the GetObject operation: The specified key does not exist.

----------------------------------------------------------------------
Ran 6 tests in 0.519s

FAILED (errors=1)

à la fin

Dans cet exemple, j'ai écrit l'évaluation d'une partie seulement de S3, mais il prend également en charge les ressources AWS suivantes.

J'ai pensé que je devais prendre l'habitude de créer régulièrement du code de test, et quand le code de test devient tout vert, j'ai l'impression que le développement est terminé. Tout d'abord, même au début.

Recommended Posts

Testé avec boto3 + mock
Testé avec Python
Utilisez Mock avec pytest
Spécification de la région avec boto
Téléchargeur S3 avec boto
Définir le délai d'expiration de la connexion avec boto3
Essayez Google Mock avec C
Modifier les paramètres de nouvelle tentative avec boto3
Testé de pipenv avec des actions GitHub
Connectez-vous à Elastic MQ avec boto
moquer
Utilisez boto3 pour accéder à S3
Générer une URL signée S3 avec boto
Utilisez boto3 avec des informations d'identification temporaires par authentification SAML
Essayez le chiffrement côté serveur de S3 à l'aide de boto3
Premiers pas avec Dynamo de Python boto
[AWS] Associez Lambda et S3 à boto3
Chiffrement côté serveur S3 SSE avec Python boto3