1111except ImportError :
1212 raise ImportError ('Model requires requests library. Install with: pip install requests' )
1313
14+ from pyosmo import Osmo
15+ from pyosmo .decorators import guard , step
16+
1417
1518class ExampleWebsiteModel :
1619 """
@@ -50,14 +53,15 @@ def after(self):
5053 # Verify response is valid
5154 assert self .response .status_code < 500 , f'Server error: { self .response .status_code } '
5255
53- # Check for error messages if we expect success
56+ # Could add more sophisticated error checking here
5457 if self .response .status_code == 200 :
55- # Could add more sophisticated error checking here
5658 pass
5759
5860 # --- Form Submission Actions ---
5961
60- def step_submit_login (self ):
62+ @step
63+ @guard (lambda self : not self .logged_in )
64+ def submit_login (self ):
6165 """Submit the login form."""
6266 data = {
6367 'username' : 'testuser' ,
@@ -77,12 +81,9 @@ def step_submit_login(self):
7781 self .current_page = 'login'
7882 print ('Executed: submit_login' )
7983
80- def guard_submit_login (self ):
81- """Guard for submit_login."""
82- # Can only login when not logged in
83- return not self .logged_in
84-
85- def step_submit_register (self ):
84+ @step
85+ @guard (lambda self : not self .logged_in )
86+ def submit_register (self ):
8687 """Submit the registration form."""
8788 data = {
8889 'username' : 'testuser' ,
@@ -99,12 +100,9 @@ def step_submit_register(self):
99100 self .current_page = 'register'
100101 print ('Executed: submit_register' )
101102
102- def guard_submit_register (self ):
103- """Guard for submit_register."""
104- # Can only register when not logged in
105- return not self .logged_in
106-
107- def step_submit_logout (self ):
103+ @step
104+ @guard (lambda self : self .logged_in )
105+ def submit_logout (self ):
108106 """Submit the logout form."""
109107 data = {}
110108
@@ -119,12 +117,8 @@ def step_submit_logout(self):
119117 self .current_page = 'logout'
120118 print ('Executed: submit_logout' )
121119
122- def guard_submit_logout (self ):
123- """Guard for submit_logout."""
124- # Can only logout when logged in
125- return self .logged_in
126-
127- def step_submit_contact (self ):
120+ @step
121+ def submit_contact (self ):
128122 """Submit the contact form."""
129123 data = {
130124 'name' : 'Test User' ,
@@ -140,11 +134,8 @@ def step_submit_contact(self):
140134 self .current_page = 'contact'
141135 print ('Executed: submit_contact' )
142136
143- def guard_submit_contact (self ):
144- """Guard for submit_contact."""
145- return True
146-
147- def step_submit_search (self ):
137+ @step
138+ def submit_search (self ):
148139 """Submit the search form."""
149140 data = {
150141 'q' : 'test_q' ,
@@ -158,70 +149,62 @@ def step_submit_search(self):
158149 self .current_page = 'search'
159150 print ('Executed: submit_search' )
160151
161- def guard_submit_search (self ):
162- """Guard for submit_search."""
163- return True
164-
165152 # --- Navigation Actions ---
166153
167- def step_navigate_to_home (self ):
154+ @step
155+ def navigate_to_home (self ):
168156 """Navigate to home."""
169157 self .response = self .session .get ('https://example.com' )
170158 self .current_page = 'home'
171159 print ('Navigated to: home' )
172160
173- def guard_navigate_to_home (self ):
174- """Guard for navigate_to_home."""
175- return True
176-
177- def step_navigate_to_about (self ):
161+ @step
162+ def navigate_to_about (self ):
178163 """Navigate to about."""
179164 self .response = self .session .get ('https://example.com/about' )
180165 self .current_page = 'about'
181166 print ('Navigated to: about' )
182167
183- def guard_navigate_to_about (self ):
184- """Guard for navigate_to_about."""
185- return True
186-
187- def step_navigate_to_contact (self ):
168+ @step
169+ def navigate_to_contact (self ):
188170 """Navigate to contact."""
189171 self .response = self .session .get ('https://example.com/contact' )
190172 self .current_page = 'contact'
191173 print ('Navigated to: contact' )
192174
193- def guard_navigate_to_contact (self ):
194- """Guard for navigate_to_contact."""
195- return True
196-
197- def step_navigate_to_login (self ):
175+ @step
176+ @guard (lambda self : not self .logged_in )
177+ def navigate_to_login (self ):
198178 """Navigate to login."""
199179 self .response = self .session .get ('https://example.com/login' )
200180 self .current_page = 'login'
201181 print ('Navigated to: login' )
202182
203- def guard_navigate_to_login (self ):
204- """Guard for navigate_to_login."""
205- # Only show login page when not logged in
206- return not self .logged_in
207-
208- def step_navigate_to_dashboard (self ):
183+ @step
184+ @guard (lambda self : self .logged_in )
185+ def navigate_to_dashboard (self ):
209186 """Navigate to dashboard."""
210187 self .response = self .session .get ('https://example.com/dashboard' )
211188 self .current_page = 'dashboard'
212189 print ('Navigated to: dashboard' )
213190
214- def guard_navigate_to_dashboard (self ):
215- """Guard for navigate_to_dashboard."""
216- # Dashboard requires authentication
217- return self .logged_in
218191
219- # --- Optional: Custom Methods ---
192+ def main ():
193+ """Run the model with PyOsmo."""
194+ model = ExampleWebsiteModel ()
195+
196+ osmo = Osmo (model ).weighted_algorithm ().stop_after_steps (100 ).run_tests (1 )
197+
198+ print (f'Starting test generation for { model .base_url } ' )
199+ osmo .generate ()
200+
201+ # Print summary
202+ stats = osmo .history .statistics ()
203+ print ('\n ' + '=' * 50 )
204+ print ('Test generation complete!' )
205+ print (f'Steps executed: { stats .total_steps } ' )
206+ print (f'Unique steps: { len (stats .step_coverage )} ' )
220207
221- def weight_submit_login (self ):
222- """Make login more likely when not logged in."""
223- return 10 if not self .logged_in else 1
224208
225- def weight_navigate_to_dashboard (self ):
226- """Dashboard is important - visit it more often when logged in."""
227- return 15 if self .logged_in else 0
209+ if __name__ == '__main__' :
210+ main ()
0 commit comments