[PYTHON] Getestet mit boto3 + mock

Einführung

Ich habe Code geschrieben, der unter AWS S3 mit boto3 funktioniert. Ich beschloss, einen Testcode zu schreiben und ihn mit Mock und Unittest zu erstellen.

Vorbereitung

Bereiten Sie zuerst die Umgebung vor. Erstellen Sie einen geeigneten Ordner und erstellen Sie eine Umgebung mit virtualenv. Dieses Mal wird davon ausgegangen, dass es auf AWS Lambda installiert wird. Danach pip boto3 und mock.

Umweltvorbereitung

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

Beispielklasse für 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):
        """
Auf S3 hochladen
        @param Bucketname S3 Bucket Name
        @param uploadfilepath Pfad der hochzuladenden Datei
        @param s3folder Ordnerpfad unter S3-Bucket (Dateiname nicht enthalten)
        """
        basefilename = os.path.basename(uploadfilepath)
        s3filepath   = s3folder + '/' + basefilename
        self.s3.upload_file(uploadfilepath, bucketname, s3filepath)

Testcode

Dieses Mal habe ich es zu einem Nur-Upload-Programm gemacht. Schreiben wir nun den Testcode. Zunächst die Umgebungskonfiguration.

Umweltzusammensetzung

Dies ist die Datei- / Ordnerstruktur. Ich wollte nur den Testcode in einem anderen Ordner erstellen (diesmal Testordner), daher sieht es wie folgt aus.

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

Testcode

Der Testcode sieht folgendermaßen aus:

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):
        #Initialisieren
        bucketname = 'testbucket001'
        prefix     = 'firstfolder'

        ##Test-Vorbereitungen(Eimer, Objekterstellung)
        s3test = boto3.client('s3')
        s3test.create_bucket(Bucket=bucketname)
        s3test.put_object(Bucket=bucketname, Key=prefix)

        #Zu testende Objekterzeugung
        s3 = S3Access()
        #Ausführung der Zielmethode
        s3.upload('./test.md', bucketname, prefix)
        
        #Bestätigung des Ausführungsergebnisses
        ##Lesen Sie die hochgeladenen Informationen aus S3
        keyname  = prefix + '/test.md'
        response = s3test.get_object(Bucket=bucketname, Key=keyname)
        body     = response['Body'].read().decode('utf-8').encode('utf-8')
        ##Laden Sie die hochgeladene Datei
        fp       = open(filename, 'r')
        readStr  = fp.read()
        fp.close
        ##Überprüfen Sie das Ergebnis
        assert body2 == readStr

Testlauf

Nachdem wir den Testcode haben, führen wir den Test tatsächlich aus.

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

OK

Jetzt wurde ein Test durchgeführt und ist erfolgreich.

Wenn es fehlschlägt

Wenn in einem Programm ein Fehler auftritt, sieht dieser folgendermaßen aus: Sie müssen lediglich die Fehlerinformationen analysieren und beheben.

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)

schließlich

In diesem Beispiel habe ich die Auswertung nur eines Teils von S3 geschrieben, aber es werden auch die folgenden AWS-Ressourcen unterstützt.

Ich dachte, ich sollte es mir zur Gewohnheit machen, regelmäßig Testcode zu erstellen, und wenn der Testcode vollständig grün wird, scheint die Entwicklung abgeschlossen zu sein. Zunächst einmal schon am Anfang.

Recommended Posts

Getestet mit boto3 + mock
Getestet mit Python
Verwenden Sie Mock mit Pytest
Regionsspezifikation mit Boto
S3 Uploader mit Boto
Stellen Sie das Verbindungszeitlimit mit boto3 ein
Versuchen Sie Google Mock mit C.
Ändern Sie die Wiederholungseinstellungen mit boto3
Pipenv mit GitHub-Aktionen getestet
Stellen Sie mit boto eine Verbindung zu Elastic MQ her
spotten
Verwenden Sie boto3, um zu S3 zu gelangen
Generieren Sie eine mit S3 signierte URL mit boto
Verwenden Sie boto3 mit temporären Anmeldeinformationen durch SAML-Authentifizierung
Versuchen Sie die serverseitige Verschlüsselung von S3 mit boto3
Erste Schritte mit Dynamo von Python Boto
[AWS] Verknüpfen Sie Lambda und S3 mit boto3
S3 serverseitige Verschlüsselung SSE mit Python boto3