11"""
2- Example integration test template for local development.
2+ Integration Test Example for python-tfe
33
4- This file shows how to create integration tests for your local development .
5- Copy this file to your tests/ directory and modify for your needs.
4+ This file demonstrates how to create integration tests that work with real HCP Terraform API .
5+ These tests create and delete actual resources, so use with caution!
66
7- Requirements:
8- 1. Set environment variables: TFE_TOKEN and TFE_ORG
9- 2. Ensure your token has appropriate permissions
10- 3. Be careful - this makes real API calls to HCP Terraform!
7+ Setup Instructions:
8+ 1. Create a test organization in HCP Terraform (https://app.terraform.io)
9+ 2. Generate an organization or user API token with appropriate permissions
10+ 3. Set environment variables:
11+ export TFE_TOKEN="your-api-token-here"
12+ export TFE_ORG="your-test-organization-name"
13+ 4. Copy this file to your tests directory:
14+ cp examples/integration_test_example.py tests/test_integration_local.py
15+ 5. Run the tests:
16+ pytest tests/test_integration_local.py -v -s
1117
12- Usage :
13- cp examples/integration_test_example.py tests/test_local_integration.py
14- export TFE_TOKEN="your-token"
15- export TFE_ORG="your-org"
16- pytest tests/test_local_integration.py -v -s
18+ Important Notes :
19+ - These tests make real API calls and create/delete actual resources
20+ - Always use a dedicated test organization, never production
21+ - Tests will fail if you don't have proper permissions
22+ - Clean up is automatic, but verify resources are deleted after testing
1723"""
1824
1925import os
26+ import uuid
27+
2028import pytest
29+
2130from tfe ._http import HTTPTransport
22- from tfe .resources .projects import Projects
2331from tfe .config import TFEConfig
32+ from tfe .resources .projects import Projects
2433
2534
2635@pytest .fixture
27- def real_projects_client ():
28- """Create a real Projects client for local integration testing"""
36+ def integration_client ():
37+ """Create a real Projects client for integration testing"""
2938 token = os .environ .get ("TFE_TOKEN" )
3039 org = os .environ .get ("TFE_ORG" )
31-
32- if not token or not org :
33- pytest .skip ("TFE_TOKEN and TFE_ORG environment variables required" )
34-
40+
41+ if not token :
42+ pytest .skip (
43+ "TFE_TOKEN environment variable is required. "
44+ "Get your token from HCP Terraform: Settings → API Tokens"
45+ )
46+
47+ if not org :
48+ pytest .skip (
49+ "TFE_ORG environment variable is required. "
50+ "Use your organization name from HCP Terraform URL"
51+ )
52+
53+ print (f"\n 🔧 Testing against organization: { org } " )
54+ print (f"🔧 Using token: { token [:10 ]} ..." )
55+
3556 config = TFEConfig ()
36- transport = HTTPTransport (
37- config .address ,
38- token ,
39- timeout = config .timeout ,
40- verify_tls = config .verify_tls ,
41- user_agent_suffix = None ,
42- max_retries = 3 ,
43- backoff_base = 0.1 ,
44- backoff_cap = 1.0 ,
45- backoff_jitter = True ,
46- http2 = False ,
47- proxies = None ,
48- ca_bundle = None ,
49- )
50-
57+
58+ try :
59+ transport = HTTPTransport (
60+ config .address ,
61+ token ,
62+ timeout = config .timeout ,
63+ verify_tls = config .verify_tls ,
64+ user_agent_suffix = None ,
65+ max_retries = 3 ,
66+ backoff_base = 0.1 ,
67+ backoff_cap = 1.0 ,
68+ backoff_jitter = True ,
69+ http2 = False ,
70+ proxies = None ,
71+ ca_bundle = None ,
72+ )
73+ except Exception as e :
74+ pytest .fail (f"Failed to create HTTP transport: { e } " )
75+
5176 return Projects (transport ), org
5277
5378
54- def test_list_projects_integration (real_projects_client ):
55- """Example integration test for listing projects"""
56- projects , org = real_projects_client
57-
58- project_list = list (projects .list (org ))
59- print (f"Found { len (project_list )} projects in organization '{ org } '" )
60-
61- assert isinstance (project_list , list )
62- # Add your assertions here
79+ def test_list_projects_integration (integration_client ):
80+ """Test listing projects in your HCP Terraform organization
81+
82+ This is the safest test to run first - it only reads data.
83+ """
84+ projects , org = integration_client
85+
86+ try :
87+ project_list = list (projects .list (org ))
88+ print (f"✅ Found { len (project_list )} projects in organization '{ org } '" )
89+
90+ assert isinstance (project_list , list )
91+
92+ if project_list :
93+ project = project_list [0 ]
94+ assert hasattr (project , 'id' ), "Project should have an ID"
95+ assert hasattr (project , 'name' ), "Project should have a name"
96+ assert hasattr (project , 'organization' ), "Project should have an organization"
97+ print (f"📋 Example project: { project .name } (ID: { project .id } )" )
98+ else :
99+ print ("📋 No projects found - this is normal for a new organization" )
63100
101+ except Exception as e :
102+ pytest .fail (
103+ f"Failed to list projects. Check your TFE_TOKEN and TFE_ORG. Error: { e } "
104+ )
64105
65- def test_project_crud_integration (real_projects_client ):
66- """Example integration test for full CRUD operations
67-
68- WARNING: This creates and deletes real resources in HCP Terraform!
106+
107+ def test_project_crud_integration (integration_client ):
108+ """Test complete Create, Read, Update, Delete operations
109+
110+ ⚠️ WARNING: This test creates and deletes real resources!
111+ Only run this in a test organization, never in production.
69112 """
70- projects , org = real_projects_client
71-
72- test_name = "example-test-project"
113+ projects , org = integration_client
114+
115+ # Generate unique names to avoid conflicts
116+ unique_id = str (uuid .uuid4 ())[:8 ]
117+ test_name = f"integration-test-{ unique_id } "
118+ updated_name = f"integration-test-{ unique_id } -updated"
73119 project_id = None
74-
120+
75121 try :
76- # CREATE
122+ # CREATE - Test project creation
123+ print (f"🔨 Creating project: { test_name } " )
77124 created_project = projects .create (org , test_name )
125+
126+ assert created_project .name == test_name , f"Expected name { test_name } , got { created_project .name } "
127+ assert created_project .organization == org , f"Expected org { org } , got { created_project .organization } "
128+ assert created_project .id .startswith ("prj-" ), f"Project ID should start with 'prj-', got { created_project .id } "
129+
78130 project_id = created_project .id
79- assert created_project .name == test_name
80-
81- # READ
131+ print (f"✅ Created project: { project_id } " )
132+
133+ # READ - Test reading the created project
134+ print (f"📖 Reading project: { project_id } " )
82135 read_project = projects .read (project_id )
83- assert read_project .id == project_id
84-
85- # UPDATE
86- updated_name = f"{ test_name } -updated"
136+
137+ assert read_project .id == project_id , f"Expected ID { project_id } , got { read_project .id } "
138+ assert read_project .name == test_name , f"Expected name { test_name } , got { read_project .name } "
139+ print (f"✅ Successfully read project: { read_project .name } " )
140+
141+ # UPDATE - Test updating the project name
142+ print (f"✏️ Updating project name to: { updated_name } " )
87143 updated_project = projects .update (project_id , updated_name )
88- assert updated_project .name == updated_name
89-
144+
145+ assert updated_project .id == project_id , f"Project ID should remain { project_id } "
146+ assert updated_project .name == updated_name , f"Expected updated name { updated_name } , got { updated_project .name } "
147+ print (f"✅ Successfully updated project: { updated_project .name } " )
148+
149+ except Exception as e :
150+ pytest .fail (f"CRUD operation failed: { e } " )
151+
90152 finally :
91- # CLEANUP - Always delete test resources
153+ # DELETE - Always clean up, even if tests fail
92154 if project_id :
93155 try :
156+ print (f"🗑️ Deleting test project: { project_id } " )
94157 projects .delete (project_id )
95- print (f "✅ Cleaned up project: { project_id } " )
158+ print ("✅ Test project deleted successfully " )
96159 except Exception as e :
97- print (f"❌ Cleanup failed: { e } " )
160+ print (f"❌ Warning: Failed to clean up project { project_id } : { e } " )
161+ print (" You may need to manually delete this project in HCP Terraform" )
162+
163+
164+ def test_error_handling_integration (integration_client ):
165+ """Test that the client handles API errors appropriately"""
166+ projects , org = integration_client
167+
168+ # Test reading a non-existent project
169+ fake_project_id = "prj-nonexistent123456789"
170+
171+ try :
172+ projects .read (fake_project_id )
173+ pytest .fail ("Should have raised an exception for non-existent project" )
174+ except Exception as e :
175+ print (f"✅ Correctly handled error for non-existent project: { type (e ).__name__ } " )
176+ # This should raise a NotFound or similar error
177+ assert "not found" in str (e ).lower () or "404" in str (e )
178+
179+
180+ if __name__ == "__main__" :
181+ """
182+ You can also run this file directly for quick testing:
183+
184+ export TFE_TOKEN="your-token"
185+ export TFE_ORG="your-org"
186+ python examples/integration_test_example.py
187+ """
188+ import sys
189+
190+ token = os .environ .get ("TFE_TOKEN" )
191+ org = os .environ .get ("TFE_ORG" )
192+
193+ if not token or not org :
194+ print ("❌ Please set TFE_TOKEN and TFE_ORG environment variables" )
195+ print (" export TFE_TOKEN='your-hcp-terraform-token'" )
196+ print (" export TFE_ORG='your-organization-name'" )
197+ sys .exit (1 )
198+
199+ print ("🧪 Running integration tests directly..." )
200+ print (" For full pytest features, use: pytest examples/integration_test_example.py -v -s" )
201+
202+ # Simple direct execution
203+ pytest .main ([__file__ , "-v" , "-s" ])
0 commit comments