Coverage for tests / test_tutorial / test_fastapi / test_teams / test_tutorial001.py: 100%

81 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-11-09 00:02 +0000

1import importlib 1jklmnopqr

2from types import ModuleType 1jklmnopqr

3 

4import pytest 1jklmnopqr

5from dirty_equals import IsOneOf 1jklmnopqr

6from fastapi.testclient import TestClient 1jklmnopqr

7from sqlalchemy import Engine 1jklmnopqr

8 

9 

10@pytest.fixture( 1jklmnopqr

11 name="module", 

12 params=[ 

13 pytest.param("tutorial001_py310"), 

14 ], 

15) 

16def get_module(request: pytest.FixtureRequest, database_engine: Engine) -> ModuleType: 1jklmnopqr

17 mod = importlib.import_module(f"docs_src.tutorial.fastapi.teams.{request.param}") 1jklmnopqr

18 mod.engine = database_engine 1jklmnopqr

19 return mod 1jklmnopqr

20 

21 

22def test_tutorial(module: ModuleType): 1jklmnopqr

23 with TestClient(module.app) as client: 1abcdefghi

24 hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} 1abcdefghi

25 hero2_data = { 1abcdefghi

26 "name": "Spider-Boy", 

27 "secret_name": "Pedro Parqueador", 

28 "id": 9000, 

29 } 

30 hero3_data = { 1abcdefghi

31 "name": "Rusty-Man", 

32 "secret_name": "Tommy Sharp", 

33 "age": 48, 

34 } 

35 response = client.post("/heroes/", json=hero1_data) 1abcdefghi

36 assert response.status_code == 200, response.text 1abcdefghi

37 response = client.post("/heroes/", json=hero2_data) 1abcdefghi

38 assert response.status_code == 200, response.text 1abcdefghi

39 hero2 = response.json() 1abcdefghi

40 hero2_id = hero2["id"] 1abcdefghi

41 response = client.post("/heroes/", json=hero3_data) 1abcdefghi

42 assert response.status_code == 200, response.text 1abcdefghi

43 response = client.get(f"/heroes/{hero2_id}") 1abcdefghi

44 assert response.status_code == 200, response.text 1abcdefghi

45 response = client.get("/heroes/9000") 1abcdefghi

46 assert response.status_code == 404, response.text 1abcdefghi

47 response = client.get("/heroes/") 1abcdefghi

48 assert response.status_code == 200, response.text 1abcdefghi

49 data = response.json() 1abcdefghi

50 assert len(data) == 3 1abcdefghi

51 response = client.patch( 1abcdefghi

52 f"/heroes/{hero2_id}", json={"secret_name": "Spider-Youngster"} 

53 ) 

54 assert response.status_code == 200, response.text 1abcdefghi

55 response = client.patch("/heroes/9001", json={"name": "Dragon Cube X"}) 1abcdefghi

56 assert response.status_code == 404, response.text 1abcdefghi

57 response = client.delete(f"/heroes/{hero2_id}") 1abcdefghi

58 assert response.status_code == 200, response.text 1abcdefghi

59 response = client.get("/heroes/") 1abcdefghi

60 assert response.status_code == 200, response.text 1abcdefghi

61 data = response.json() 1abcdefghi

62 assert len(data) == 2 1abcdefghi

63 response = client.delete("/heroes/9000") 1abcdefghi

64 assert response.status_code == 404, response.text 1abcdefghi

65 

66 team_preventers = {"name": "Preventers", "headquarters": "Sharp Tower"} 1abcdefghi

67 team_z_force = {"name": "Z-Force", "headquarters": "Sister Margaret's Bar"} 1abcdefghi

68 response = client.post("/teams/", json=team_preventers) 1abcdefghi

69 assert response.status_code == 200, response.text 1abcdefghi

70 team_preventers_data = response.json() 1abcdefghi

71 team_preventers_id = team_preventers_data["id"] 1abcdefghi

72 response = client.post("/teams/", json=team_z_force) 1abcdefghi

73 assert response.status_code == 200, response.text 1abcdefghi

74 team_z_force_data = response.json() 1abcdefghi

75 team_z_force_data["id"] 1abcdefghi

76 response = client.get("/teams/") 1abcdefghi

77 data = response.json() 1abcdefghi

78 assert len(data) == 2 1abcdefghi

79 response = client.get(f"/teams/{team_preventers_id}") 1abcdefghi

80 data = response.json() 1abcdefghi

81 assert response.status_code == 200, response.text 1abcdefghi

82 assert data == team_preventers_data 1abcdefghi

83 response = client.get("/teams/9000") 1abcdefghi

84 assert response.status_code == 404, response.text 1abcdefghi

85 response = client.patch( 1abcdefghi

86 f"/teams/{team_preventers_id}", json={"headquarters": "Preventers Tower"} 

87 ) 

88 data = response.json() 1abcdefghi

89 assert response.status_code == 200, response.text 1abcdefghi

90 assert data["name"] == team_preventers["name"] 1abcdefghi

91 assert data["headquarters"] == "Preventers Tower" 1abcdefghi

92 response = client.patch("/teams/9000", json={"name": "Freedom League"}) 1abcdefghi

93 assert response.status_code == 404, response.text 1abcdefghi

94 response = client.delete(f"/teams/{team_preventers_id}") 1abcdefghi

95 assert response.status_code == 200, response.text 1abcdefghi

96 response = client.delete("/teams/9000") 1abcdefghi

97 assert response.status_code == 404, response.text 1abcdefghi

98 response = client.get("/teams/") 1abcdefghi

99 assert response.status_code == 200, response.text 1abcdefghi

100 data = response.json() 1abcdefghi

101 assert len(data) == 1 1abcdefghi

102 

103 response = client.get("/openapi.json") 1abcdefghi

104 assert response.status_code == 200, response.text 1abcdefghi

105 assert response.json() == { 1abcdefghi

106 "openapi": "3.1.0", 

107 "info": {"title": "FastAPI", "version": "0.1.0"}, 

108 "paths": { 

109 "/heroes/": { 

110 "get": { 

111 "summary": "Read Heroes", 

112 "operationId": "read_heroes_heroes__get", 

113 "parameters": [ 

114 { 

115 "required": False, 

116 "schema": { 

117 "title": "Offset", 

118 "type": "integer", 

119 "default": 0, 

120 }, 

121 "name": "offset", 

122 "in": "query", 

123 }, 

124 { 

125 "required": False, 

126 "schema": { 

127 "title": "Limit", 

128 "maximum": 100.0, 

129 "type": "integer", 

130 "default": 100, 

131 }, 

132 "name": "limit", 

133 "in": "query", 

134 }, 

135 ], 

136 "responses": { 

137 "200": { 

138 "description": "Successful Response", 

139 "content": { 

140 "application/json": { 

141 "schema": { 

142 "title": "Response Read Heroes Heroes Get", 

143 "type": "array", 

144 "items": { 

145 "$ref": "#/components/schemas/HeroPublic" 

146 }, 

147 } 

148 } 

149 }, 

150 }, 

151 "422": { 

152 "description": "Validation Error", 

153 "content": { 

154 "application/json": { 

155 "schema": { 

156 "$ref": "#/components/schemas/HTTPValidationError" 

157 } 

158 } 

159 }, 

160 }, 

161 }, 

162 }, 

163 "post": { 

164 "summary": "Create Hero", 

165 "operationId": "create_hero_heroes__post", 

166 "requestBody": { 

167 "content": { 

168 "application/json": { 

169 "schema": { 

170 "$ref": "#/components/schemas/HeroCreate" 

171 } 

172 } 

173 }, 

174 "required": True, 

175 }, 

176 "responses": { 

177 "200": { 

178 "description": "Successful Response", 

179 "content": { 

180 "application/json": { 

181 "schema": { 

182 "$ref": "#/components/schemas/HeroPublic" 

183 } 

184 } 

185 }, 

186 }, 

187 "422": { 

188 "description": "Validation Error", 

189 "content": { 

190 "application/json": { 

191 "schema": { 

192 "$ref": "#/components/schemas/HTTPValidationError" 

193 } 

194 } 

195 }, 

196 }, 

197 }, 

198 }, 

199 }, 

200 "/heroes/{hero_id}": { 

201 "get": { 

202 "summary": "Read Hero", 

203 "operationId": "read_hero_heroes__hero_id__get", 

204 "parameters": [ 

205 { 

206 "required": True, 

207 "schema": {"title": "Hero Id", "type": "integer"}, 

208 "name": "hero_id", 

209 "in": "path", 

210 } 

211 ], 

212 "responses": { 

213 "200": { 

214 "description": "Successful Response", 

215 "content": { 

216 "application/json": { 

217 "schema": { 

218 "$ref": "#/components/schemas/HeroPublic" 

219 } 

220 } 

221 }, 

222 }, 

223 "422": { 

224 "description": "Validation Error", 

225 "content": { 

226 "application/json": { 

227 "schema": { 

228 "$ref": "#/components/schemas/HTTPValidationError" 

229 } 

230 } 

231 }, 

232 }, 

233 }, 

234 }, 

235 "delete": { 

236 "summary": "Delete Hero", 

237 "operationId": "delete_hero_heroes__hero_id__delete", 

238 "parameters": [ 

239 { 

240 "required": True, 

241 "schema": {"title": "Hero Id", "type": "integer"}, 

242 "name": "hero_id", 

243 "in": "path", 

244 } 

245 ], 

246 "responses": { 

247 "200": { 

248 "description": "Successful Response", 

249 "content": {"application/json": {"schema": {}}}, 

250 }, 

251 "422": { 

252 "description": "Validation Error", 

253 "content": { 

254 "application/json": { 

255 "schema": { 

256 "$ref": "#/components/schemas/HTTPValidationError" 

257 } 

258 } 

259 }, 

260 }, 

261 }, 

262 }, 

263 "patch": { 

264 "summary": "Update Hero", 

265 "operationId": "update_hero_heroes__hero_id__patch", 

266 "parameters": [ 

267 { 

268 "required": True, 

269 "schema": {"title": "Hero Id", "type": "integer"}, 

270 "name": "hero_id", 

271 "in": "path", 

272 } 

273 ], 

274 "requestBody": { 

275 "content": { 

276 "application/json": { 

277 "schema": { 

278 "$ref": "#/components/schemas/HeroUpdate" 

279 } 

280 } 

281 }, 

282 "required": True, 

283 }, 

284 "responses": { 

285 "200": { 

286 "description": "Successful Response", 

287 "content": { 

288 "application/json": { 

289 "schema": { 

290 "$ref": "#/components/schemas/HeroPublic" 

291 } 

292 } 

293 }, 

294 }, 

295 "422": { 

296 "description": "Validation Error", 

297 "content": { 

298 "application/json": { 

299 "schema": { 

300 "$ref": "#/components/schemas/HTTPValidationError" 

301 } 

302 } 

303 }, 

304 }, 

305 }, 

306 }, 

307 }, 

308 "/teams/": { 

309 "get": { 

310 "summary": "Read Teams", 

311 "operationId": "read_teams_teams__get", 

312 "parameters": [ 

313 { 

314 "required": False, 

315 "schema": { 

316 "title": "Offset", 

317 "type": "integer", 

318 "default": 0, 

319 }, 

320 "name": "offset", 

321 "in": "query", 

322 }, 

323 { 

324 "required": False, 

325 "schema": { 

326 "title": "Limit", 

327 "maximum": 100.0, 

328 "type": "integer", 

329 "default": 100, 

330 }, 

331 "name": "limit", 

332 "in": "query", 

333 }, 

334 ], 

335 "responses": { 

336 "200": { 

337 "description": "Successful Response", 

338 "content": { 

339 "application/json": { 

340 "schema": { 

341 "title": "Response Read Teams Teams Get", 

342 "type": "array", 

343 "items": { 

344 "$ref": "#/components/schemas/TeamPublic" 

345 }, 

346 } 

347 } 

348 }, 

349 }, 

350 "422": { 

351 "description": "Validation Error", 

352 "content": { 

353 "application/json": { 

354 "schema": { 

355 "$ref": "#/components/schemas/HTTPValidationError" 

356 } 

357 } 

358 }, 

359 }, 

360 }, 

361 }, 

362 "post": { 

363 "summary": "Create Team", 

364 "operationId": "create_team_teams__post", 

365 "requestBody": { 

366 "content": { 

367 "application/json": { 

368 "schema": { 

369 "$ref": "#/components/schemas/TeamCreate" 

370 } 

371 } 

372 }, 

373 "required": True, 

374 }, 

375 "responses": { 

376 "200": { 

377 "description": "Successful Response", 

378 "content": { 

379 "application/json": { 

380 "schema": { 

381 "$ref": "#/components/schemas/TeamPublic" 

382 } 

383 } 

384 }, 

385 }, 

386 "422": { 

387 "description": "Validation Error", 

388 "content": { 

389 "application/json": { 

390 "schema": { 

391 "$ref": "#/components/schemas/HTTPValidationError" 

392 } 

393 } 

394 }, 

395 }, 

396 }, 

397 }, 

398 }, 

399 "/teams/{team_id}": { 

400 "get": { 

401 "summary": "Read Team", 

402 "operationId": "read_team_teams__team_id__get", 

403 "parameters": [ 

404 { 

405 "required": True, 

406 "schema": {"title": "Team Id", "type": "integer"}, 

407 "name": "team_id", 

408 "in": "path", 

409 } 

410 ], 

411 "responses": { 

412 "200": { 

413 "description": "Successful Response", 

414 "content": { 

415 "application/json": { 

416 "schema": { 

417 "$ref": "#/components/schemas/TeamPublic" 

418 } 

419 } 

420 }, 

421 }, 

422 "422": { 

423 "description": "Validation Error", 

424 "content": { 

425 "application/json": { 

426 "schema": { 

427 "$ref": "#/components/schemas/HTTPValidationError" 

428 } 

429 } 

430 }, 

431 }, 

432 }, 

433 }, 

434 "delete": { 

435 "summary": "Delete Team", 

436 "operationId": "delete_team_teams__team_id__delete", 

437 "parameters": [ 

438 { 

439 "required": True, 

440 "schema": {"title": "Team Id", "type": "integer"}, 

441 "name": "team_id", 

442 "in": "path", 

443 } 

444 ], 

445 "responses": { 

446 "200": { 

447 "description": "Successful Response", 

448 "content": {"application/json": {"schema": {}}}, 

449 }, 

450 "422": { 

451 "description": "Validation Error", 

452 "content": { 

453 "application/json": { 

454 "schema": { 

455 "$ref": "#/components/schemas/HTTPValidationError" 

456 } 

457 } 

458 }, 

459 }, 

460 }, 

461 }, 

462 "patch": { 

463 "summary": "Update Team", 

464 "operationId": "update_team_teams__team_id__patch", 

465 "parameters": [ 

466 { 

467 "required": True, 

468 "schema": {"title": "Team Id", "type": "integer"}, 

469 "name": "team_id", 

470 "in": "path", 

471 } 

472 ], 

473 "requestBody": { 

474 "content": { 

475 "application/json": { 

476 "schema": { 

477 "$ref": "#/components/schemas/TeamUpdate" 

478 } 

479 } 

480 }, 

481 "required": True, 

482 }, 

483 "responses": { 

484 "200": { 

485 "description": "Successful Response", 

486 "content": { 

487 "application/json": { 

488 "schema": { 

489 "$ref": "#/components/schemas/TeamPublic" 

490 } 

491 } 

492 }, 

493 }, 

494 "422": { 

495 "description": "Validation Error", 

496 "content": { 

497 "application/json": { 

498 "schema": { 

499 "$ref": "#/components/schemas/HTTPValidationError" 

500 } 

501 } 

502 }, 

503 }, 

504 }, 

505 }, 

506 }, 

507 }, 

508 "components": { 

509 "schemas": { 

510 "HTTPValidationError": { 

511 "title": "HTTPValidationError", 

512 "type": "object", 

513 "properties": { 

514 "detail": { 

515 "title": "Detail", 

516 "type": "array", 

517 "items": { 

518 "$ref": "#/components/schemas/ValidationError" 

519 }, 

520 } 

521 }, 

522 }, 

523 "HeroCreate": { 

524 "title": "HeroCreate", 

525 "required": ["name", "secret_name"], 

526 "type": "object", 

527 "properties": { 

528 "name": {"title": "Name", "type": "string"}, 

529 "secret_name": {"title": "Secret Name", "type": "string"}, 

530 "age": { 

531 "title": "Age", 

532 "anyOf": [{"type": "integer"}, {"type": "null"}], 

533 }, 

534 "team_id": { 

535 "title": "Team Id", 

536 "anyOf": [{"type": "integer"}, {"type": "null"}], 

537 }, 

538 }, 

539 }, 

540 "HeroPublic": { 

541 "title": "HeroPublic", 

542 "required": ["name", "secret_name", "id"], 

543 "type": "object", 

544 "properties": { 

545 "name": {"title": "Name", "type": "string"}, 

546 "secret_name": {"title": "Secret Name", "type": "string"}, 

547 "age": { 

548 "title": "Age", 

549 "anyOf": [{"type": "integer"}, {"type": "null"}], 

550 }, 

551 "team_id": { 

552 "title": "Team Id", 

553 "anyOf": [{"type": "integer"}, {"type": "null"}], 

554 }, 

555 "id": {"title": "Id", "type": "integer"}, 

556 }, 

557 }, 

558 "HeroUpdate": { 

559 "title": "HeroUpdate", 

560 "type": "object", 

561 "properties": { 

562 "name": { 

563 "title": "Name", 

564 "anyOf": [{"type": "string"}, {"type": "null"}], 

565 }, 

566 "secret_name": { 

567 "title": "Secret Name", 

568 "anyOf": [{"type": "string"}, {"type": "null"}], 

569 }, 

570 "age": { 

571 "title": "Age", 

572 "anyOf": [{"type": "integer"}, {"type": "null"}], 

573 }, 

574 "team_id": { 

575 "title": "Team Id", 

576 "anyOf": [{"type": "integer"}, {"type": "null"}], 

577 }, 

578 }, 

579 }, 

580 "TeamCreate": { 

581 "title": "TeamCreate", 

582 "required": ["name", "headquarters"], 

583 "type": "object", 

584 "properties": { 

585 "name": {"title": "Name", "type": "string"}, 

586 "headquarters": {"title": "Headquarters", "type": "string"}, 

587 }, 

588 }, 

589 "TeamPublic": { 

590 "title": "TeamPublic", 

591 "required": ["name", "headquarters", "id"], 

592 "type": "object", 

593 "properties": { 

594 "name": {"title": "Name", "type": "string"}, 

595 "headquarters": {"title": "Headquarters", "type": "string"}, 

596 "id": {"title": "Id", "type": "integer"}, 

597 }, 

598 }, 

599 "TeamUpdate": { 

600 "title": "TeamUpdate", 

601 "type": "object", 

602 "properties": { 

603 "name": { 

604 "title": "Name", 

605 "anyOf": [{"type": "string"}, {"type": "null"}], 

606 }, 

607 "headquarters": { 

608 "title": "Headquarters", 

609 "anyOf": [{"type": "string"}, {"type": "null"}], 

610 }, 

611 }, 

612 }, 

613 "ValidationError": { 

614 "title": "ValidationError", 

615 "required": ["loc", "msg", "type"], 

616 "type": "object", 

617 "properties": IsOneOf( 

618 { 

619 "loc": { 

620 "title": "Location", 

621 "type": "array", 

622 "items": { 

623 "anyOf": [ 

624 {"type": "string"}, 

625 {"type": "integer"}, 

626 ] 

627 }, 

628 }, 

629 "msg": {"title": "Message", "type": "string"}, 

630 "type": {"title": "Error Type", "type": "string"}, 

631 }, 

632 { 

633 "loc": { 

634 "title": "Location", 

635 "type": "array", 

636 "items": { 

637 "anyOf": [ 

638 {"type": "string"}, 

639 {"type": "integer"}, 

640 ] 

641 }, 

642 }, 

643 "msg": {"title": "Message", "type": "string"}, 

644 "type": {"title": "Error Type", "type": "string"}, 

645 "ctx": {"title": "Context", "type": "object"}, 

646 "input": {"title": "Input"}, 

647 }, 

648 ), 

649 }, 

650 } 

651 }, 

652 }