Testing der MILKEE API
Diese Seite bietet Ihnen verschiedene Tools und Methoden zum Testen der MILKEE API, bevor Sie sie in Ihre Produktionsumgebung integrieren.
Schnelltest
API-Verbindung testen
Verwenden Sie diesen einfachen cURL-Befehl, um zu testen, ob Ihr API-Token funktioniert:
bash
curl -H "Authorization: Bearer IHR_TOKEN_HIER" \
https://app.milkee.ch/api/v2/companies/COMPANY_ID/tags/colors
Erwartete Antwort:
json
[
"orange",
"blue",
"lime",
"yellow",
"turquoise",
"marine",
"purple",
"pink",
"green",
"red",
"gray"
]
Häufige Test-Fehler
Status Code | Bedeutung | Lösung |
---|---|---|
401 | Token ungültig | Token in MILKEE-Einstellungen überprüfen |
402 | Abo abgelaufen | Business Plan erneuern |
403 | Keine Berechtigung | Firmen-ID überprüfen |
404 | Endpoint nicht gefunden | URL-Struktur überprüfen |
Browser-Testing
Fetch API im Browser
Öffnen Sie die Browser-Konsole auf einer beliebigen HTTPS-Website und führen Sie folgenden Code aus:
javascript
// Ihre Konfiguration
const token = 'IHR_TOKEN_HIER';
const companyId = 123;
const baseURL = 'https://app.milkee.ch/api/v2';
// API-Test Funktion
async function testMilkeeAPI() {
try {
// 1. Farben abrufen (einfachster Test)
console.log('🧪 Teste API-Verbindung...');
const colorsResponse = await fetch(`${baseURL}/companies/${companyId}/tags/colors`, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (!colorsResponse.ok) {
throw new Error(`HTTP ${colorsResponse.status}: ${colorsResponse.statusText}`);
}
const colors = await colorsResponse.json();
console.log('✅ API-Verbindung erfolgreich');
console.log('📋 Verfügbare Farben:', colors);
// 2. Tags abrufen
console.log('🧪 Teste Tags abrufen...');
const tagsResponse = await fetch(`${baseURL}/companies/${companyId}/tags`, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
const tagsData = await tagsResponse.json();
console.log('✅ Tags erfolgreich abgerufen');
console.log(`📊 ${tagsData.data.length} Tags gefunden (Seite ${tagsData.meta.current_page} von ${tagsData.meta.last_page})`);
// 3. Test-Tag erstellen
console.log('🧪 Teste Tag erstellen...');
const createResponse = await fetch(`${baseURL}/companies/${companyId}/tags`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: `test-tag-${Date.now()}`,
color: colors[Math.floor(Math.random() * colors.length)]
})
});
const newTag = await createResponse.json();
console.log('✅ Tag erfolgreich erstellt');
console.log('🏷️ Neuer Tag:', newTag);
// 4. Tag wieder löschen (Cleanup)
console.log('🧪 Teste Tag löschen...');
const deleteResponse = await fetch(`${baseURL}/companies/${companyId}/tags/${newTag.id}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
const deleteResult = await deleteResponse.json();
console.log('✅ Tag erfolgreich gelöscht');
console.log('🗑️ Löschung:', deleteResult);
console.log('🎉 Alle Tests erfolgreich!');
} catch (error) {
console.error('❌ Test fehlgeschlagen:', error.message);
// Spezifische Fehlerdiagnose
if (error.message.includes('401')) {
console.error('💡 Lösung: API-Token in MILKEE-Einstellungen überprüfen');
} else if (error.message.includes('402')) {
console.error('💡 Lösung: Business Plan erneuern');
} else if (error.message.includes('403')) {
console.error('💡 Lösung: Firmen-ID überprüfen');
} else if (error.message.includes('CORS')) {
console.error('💡 Info: CORS-Fehler sind normal im Browser, API funktioniert trotzdem');
}
}
}
// Test ausführen
testMilkeeAPI();
Online API-Tester
Für schnelle Tests ohne Programmierung können Sie Online-Tools verwenden:
Automatisierte Tests
Node.js Test Suite
Erstellen Sie automatisierte Tests mit Jest:
javascript
// milkee-api.test.js
const fetch = require('node-fetch');
const API_TOKEN = process.env.MILKEE_API_TOKEN;
const COMPANY_ID = process.env.MILKEE_COMPANY_ID;
const BASE_URL = 'https://app.milkee.ch/api/v2';
describe('MILKEE API Tests', () => {
let testTagId;
beforeAll(() => {
if (!API_TOKEN || !COMPANY_ID) {
throw new Error('MILKEE_API_TOKEN und MILKEE_COMPANY_ID müssen gesetzt sein');
}
});
async function apiRequest(endpoint, options = {}) {
const response = await fetch(`${BASE_URL}/companies/${COMPANY_ID}${endpoint}`, {
headers: {
'Authorization': `Bearer ${API_TOKEN}`,
'Content-Type': 'application/json',
...options.headers
},
...options
});
if (!response.ok) {
const error = await response.text();
throw new Error(`HTTP ${response.status}: ${error}`);
}
return response.json();
}
test('sollte verfügbare Farben abrufen können', async () => {
const colors = await apiRequest('/tags/colors');
expect(Array.isArray(colors)).toBe(true);
expect(colors).toContain('blue');
expect(colors).toContain('red');
expect(colors.length).toBeGreaterThan(5);
});
test('sollte alle Tags abrufen können', async () => {
const response = await apiRequest('/tags');
expect(response).toHaveProperty('data');
expect(response).toHaveProperty('meta');
expect(response).toHaveProperty('links');
expect(Array.isArray(response.data)).toBe(true);
});
test('sollte einen Tag erstellen können', async () => {
const tagData = {
name: `test-tag-${Date.now()}`,
color: 'blue'
};
const newTag = await apiRequest('/tags', {
method: 'POST',
body: JSON.stringify(tagData)
});
expect(newTag).toHaveProperty('id');
expect(newTag.name).toBe(tagData.name);
expect(newTag.color).toBe(tagData.color);
testTagId = newTag.id; // Für spätere Tests speichern
});
test('sollte einen spezifischen Tag abrufen können', async () => {
if (!testTagId) {
throw new Error('testTagId nicht verfügbar - vorheriger Test fehlgeschlagen?');
}
const tag = await apiRequest(`/tags/${testTagId}`);
expect(tag).toHaveProperty('id', testTagId);
expect(tag).toHaveProperty('name');
expect(tag).toHaveProperty('color');
});
test('sollte einen Tag aktualisieren können', async () => {
if (!testTagId) {
throw new Error('testTagId nicht verfügbar - vorheriger Test fehlgeschlagen?');
}
const updateData = {
name: `updated-tag-${Date.now()}`,
color: 'red'
};
const updatedTag = await apiRequest(`/tags/${testTagId}`, {
method: 'PUT',
body: JSON.stringify(updateData)
});
expect(updatedTag.id).toBe(testTagId);
expect(updatedTag.name).toBe(updateData.name);
expect(updatedTag.color).toBe(updateData.color);
});
test('sollte einen Tag löschen können', async () => {
if (!testTagId) {
throw new Error('testTagId nicht verfügbar - vorheriger Test fehlgeschlagen?');
}
const result = await apiRequest(`/tags/${testTagId}`, {
method: 'DELETE'
});
expect(result).toHaveProperty('message');
expect(result.message).toContain('deleted successfully');
});
});
Test ausführen:
bash
# Jest installieren
npm install --save-dev jest node-fetch
# Environment Variablen setzen und Tests ausführen
MILKEE_API_TOKEN="1|ihr_token" MILKEE_COMPANY_ID="123" npm test
Python Test Suite
Mit pytest und requests:
python
# test_milkee_api.py
import pytest
import requests
import os
import time
API_TOKEN = os.environ.get('MILKEE_API_TOKEN')
COMPANY_ID = os.environ.get('MILKEE_COMPANY_ID')
BASE_URL = 'https://app.milkee.ch/api/v2'
@pytest.fixture
def api_headers():
return {
'Authorization': f'Bearer {API_TOKEN}',
'Content-Type': 'application/json'
}
@pytest.fixture
def test_tag(api_headers):
"""Erstellt einen Test-Tag und löscht ihn nach dem Test"""
tag_data = {
'name': f'pytest-tag-{int(time.time())}',
'color': 'blue'
}
response = requests.post(
f'{BASE_URL}/companies/{COMPANY_ID}/tags',
json=tag_data,
headers=api_headers
)
response.raise_for_status()
tag = response.json()
yield tag
# Cleanup
requests.delete(
f'{BASE_URL}/companies/{COMPANY_ID}/tags/{tag["id"]}',
headers=api_headers
)
class TestMilkeeAPI:
def test_get_colors(self, api_headers):
response = requests.get(
f'{BASE_URL}/companies/{COMPANY_ID}/tags/colors',
headers=api_headers
)
response.raise_for_status()
colors = response.json()
assert isinstance(colors, list)
assert 'blue' in colors
assert 'red' in colors
def test_get_tags(self, api_headers):
response = requests.get(
f'{BASE_URL}/companies/{COMPANY_ID}/tags',
headers=api_headers
)
response.raise_for_status()
data = response.json()
assert 'data' in data
assert 'meta' in data
assert 'links' in data
def test_create_tag(self, api_headers):
tag_data = {
'name': f'pytest-create-{int(time.time())}',
'color': 'green'
}
response = requests.post(
f'{BASE_URL}/companies/{COMPANY_ID}/tags',
json=tag_data,
headers=api_headers
)
response.raise_for_status()
tag = response.json()
assert tag['name'] == tag_data['name']
assert tag['color'] == tag_data['color']
assert 'id' in tag
# Cleanup
requests.delete(
f'{BASE_URL}/companies/{COMPANY_ID}/tags/{tag["id"]}',
headers=api_headers
)
def test_get_single_tag(self, api_headers, test_tag):
response = requests.get(
f'{BASE_URL}/companies/{COMPANY_ID}/tags/{test_tag["id"]}',
headers=api_headers
)
response.raise_for_status()
tag = response.json()
assert tag['id'] == test_tag['id']
assert tag['name'] == test_tag['name']
def test_update_tag(self, api_headers, test_tag):
update_data = {
'name': f'pytest-updated-{int(time.time())}',
'color': 'purple'
}
response = requests.put(
f'{BASE_URL}/companies/{COMPANY_ID}/tags/{test_tag["id"]}',
json=update_data,
headers=api_headers
)
response.raise_for_status()
updated_tag = response.json()
assert updated_tag['id'] == test_tag['id']
assert updated_tag['name'] == update_data['name']
assert updated_tag['color'] == update_data['color']
def test_delete_tag(self, api_headers):
# Erst einen Tag erstellen
tag_data = {
'name': f'pytest-delete-{int(time.time())}',
'color': 'red'
}
create_response = requests.post(
f'{BASE_URL}/companies/{COMPANY_ID}/tags',
json=tag_data,
headers=api_headers
)
create_response.raise_for_status()
tag = create_response.json()
# Dann löschen
delete_response = requests.delete(
f'{BASE_URL}/companies/{COMPANY_ID}/tags/{tag["id"]}',
headers=api_headers
)
delete_response.raise_for_status()
result = delete_response.json()
assert 'message' in result
assert 'deleted successfully' in result['message']
Tests ausführen:
bash
# pytest installieren
pip install pytest requests
# Tests ausführen
MILKEE_API_TOKEN="1|ihr_token" MILKEE_COMPANY_ID="123" pytest test_milkee_api.py -v
Performance Testing
Einfacher Load Test
bash
#!/bin/bash
# load_test.sh
TOKEN="1|ihr_token"
COMPANY_ID="123"
BASE_URL="https://app.milkee.ch/api/v2"
echo "🚀 Starte Load Test..."
# 10 parallele Requests
for i in {1..10}; do
{
echo "Request $i gestartet..."
time curl -s \
-H "Authorization: Bearer $TOKEN" \
"$BASE_URL/companies/$COMPANY_ID/tags/colors" \
> /dev/null
echo "Request $i abgeschlossen"
} &
done
wait
echo "✅ Load Test abgeschlossen"
Rate Limit Test
javascript
// rate_limit_test.js
const fetch = require('node-fetch');
const TOKEN = process.env.MILKEE_API_TOKEN;
const COMPANY_ID = process.env.MILKEE_COMPANY_ID;
const BASE_URL = 'https://app.milkee.ch/api/v2';
async function testRateLimit() {
const requests = [];
const results = [];
console.log('🧪 Teste Rate Limits...');
// 70 Requests in kurzer Zeit (Limit ist 60/Minute)
for (let i = 0; i < 70; i++) {
const request = fetch(`${BASE_URL}/companies/${COMPANY_ID}/tags/colors`, {
headers: {
'Authorization': `Bearer ${TOKEN}`
}
}).then(response => ({
status: response.status,
headers: {
rateLimit: response.headers.get('X-RateLimit-Limit'),
remaining: response.headers.get('X-RateLimit-Remaining'),
}
})).catch(error => ({
error: error.message
}));
requests.push(request);
}
const responses = await Promise.all(requests);
responses.forEach((response, index) => {
if (response.status === 429) {
console.log(`❌ Request ${index + 1}: Rate Limit erreicht`);
} else if (response.status === 200) {
console.log(`✅ Request ${index + 1}: OK (Remaining: ${response.headers.remaining})`);
} else {
console.log(`⚠️ Request ${index + 1}: Status ${response.status}`);
}
});
const rateLimitHits = responses.filter(r => r.status === 429).length;
console.log(`\n📊 Ergebnis: ${rateLimitHits} von ${responses.length} Requests erreichten das Rate Limit`);
}
testRateLimit();
Test-Automation
GitHub Actions CI/CD
yaml
# .github/workflows/api-tests.yml
name: MILKEE API Tests
on:
schedule:
- cron: '0 9 * * *' # Täglich um 9 Uhr
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
api-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run API Tests
env:
MILKEE_API_TOKEN: ${{ secrets.MILKEE_API_TOKEN }}
MILKEE_COMPANY_ID: ${{ secrets.MILKEE_COMPANY_ID }}
run: npm test
- name: Upload test results
uses: actions/upload-artifact@v2
if: always()
with:
name: test-results
path: test-results/
Monitoring & Alerting
API Health Check Script
bash
#!/bin/bash
# health_check.sh
TOKEN="$MILKEE_API_TOKEN"
COMPANY_ID="$MILKEE_COMPANY_ID"
WEBHOOK_URL="$SLACK_WEBHOOK_URL" # Optional: Slack Notifications
check_api() {
local endpoint="$1"
local name="$2"
echo "Prüfe $name..."
response=$(curl -s -w "%{http_code}" \
-H "Authorization: Bearer $TOKEN" \
"https://app.milkee.ch/api/v2/companies/$COMPANY_ID$endpoint")
http_code="${response: -3}"
if [ "$http_code" = "200" ]; then
echo "✅ $name: OK"
return 0
else
echo "❌ $name: HTTP $http_code"
# Optional: Slack Benachrichtigung
if [ ! -z "$WEBHOOK_URL" ]; then
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"🚨 MILKEE API Alert: $name failed with HTTP $http_code\"}" \
"$WEBHOOK_URL"
fi
return 1
fi
}
echo "🔍 MILKEE API Health Check $(date)"
echo "================================"
check_api "/tags/colors" "Tag Colors Endpoint"
check_api "/tags" "Tags List Endpoint"
echo "================================"
echo "Health Check abgeschlossen"