From 83d54044f7a431fce73dc47f86dac116add25537 Mon Sep 17 00:00:00 2001 From: samt07 Date: Fri, 31 Jan 2025 23:23:18 -0500 Subject: [PATCH] Added test case automation solution --- week1/community-contributions/reqdoc.docx | Bin 0 -> 37730 bytes .../testcase_automation.ipynb | 308 ++++++++++++++++++ 2 files changed, 308 insertions(+) create mode 100644 week1/community-contributions/reqdoc.docx create mode 100644 week1/community-contributions/testcase_automation.ipynb diff --git a/week1/community-contributions/reqdoc.docx b/week1/community-contributions/reqdoc.docx new file mode 100644 index 0000000000000000000000000000000000000000..0a5a76a458214be1d15275908b90c1feebf1160e GIT binary patch literal 37730 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 p%3Tpiyuds-9^~^2@vF9&V036}B?|1I10:\n", + " print(\"API key looks good!\")\n", + "else:\n", + " print(\"There might be a problem with your API key. Please check!\")\n", + " \n", + "MODEL = 'gpt-4o-mini'\n", + "openai = OpenAI()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6110ff3-74bc-430a-8051-7d86a216f0fb", + "metadata": { + "id": "b6110ff3-74bc-430a-8051-7d86a216f0fb" + }, + "outputs": [], + "source": [ + "#Set up system prompt for extracting just the requirements from the document\n", + "\n", + "req_doc_system_prompt = \"You are provided with a complete requirements specifications document. \\\n", + "You are able to decide which content from that document are related to actual requirements, identify each requirement as \\\n", + "functional or non-functional and list them all.\\n\"\n", + "req_doc_system_prompt += \"If the document is empty or do not contain requirements or if you cannot extract them, please respond as such.\\\n", + "Do not make up your own requirements. \\n\"\n", + "req_doc_system_prompt += \"You should respond in JSON as in this example:\"\n", + "req_doc_system_prompt += \"\"\"\n", + "{\n", + " \"requirements\": [\n", + " {\"RequirementNo\": \"FR-01\", \"Requirement Description\": \"description of this functional requirement goes here\"},\n", + " {\"RequirementNo\": \"FR-02\": \"Requirement Description\": \"description of this functional requirement goes here\"},\n", + " {\"RequirementNo\": \"NFR-01\": \"Requirement Description\": \"description of this non-functional requirement goes here\"},\n", + " {\"RequirementNo\": \"NFR-02\": \"Requirement Description\": \"description of this non-functional requirement goes here\"}\n", + " ]\n", + "}\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20460e45-c1b7-4dc4-ab07-932235c19895", + "metadata": { + "id": "20460e45-c1b7-4dc4-ab07-932235c19895" + }, + "outputs": [], + "source": [ + "#Set up user prompt, sending in the requirements doc as input and calling the ReqDoc.extract function. Key to note here is the explicit instructions to\n", + "#respond in JSON format.\n", + "\n", + "def req_doc_user_prompt(doc):\n", + " user_prompt = \"Here is the contents from a requirement document.\\n\"\n", + " user_prompt += f\"{doc.extract()} \\n\"\n", + " user_prompt += \"Please scan through the document and extract only the actual requirements. For example, ignore sections or \\\n", + "paragraphs such as Approvers, table of contents and similar sections which are not really requirements.\\\n", + "You must respond in a JSON format\"\n", + " user_prompt += \"If the content is empty, respond that there are no valid requirements you could extract and ask for a proper document.\\n\"\n", + " user_prompt = user_prompt[:25_000] # Truncate if more than 25,000 characters\n", + " return user_prompt\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a9f0f84-69a0-4971-a545-5bb40c2f9891", + "metadata": { + "id": "3a9f0f84-69a0-4971-a545-5bb40c2f9891" + }, + "outputs": [], + "source": [ + "#Function to call chatgpt-4o-mini model with the user and system prompts set above and returning the json formatted result obtained from chatgpt\n", + "\n", + "def get_requirements(doc):\n", + " reqdoc = ReqDoc(doc)\n", + " response = openai.chat.completions.create(\n", + " model=MODEL,\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": req_doc_system_prompt},\n", + " {\"role\": \"user\", \"content\": req_doc_user_prompt(reqdoc)}\n", + " ],\n", + " response_format={\"type\": \"json_object\"}\n", + " )\n", + " result = response.choices[0].message.content\n", + " return json.loads(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f9bb04ef-78d3-4e0f-9ed1-59a961a0663e", + "metadata": { + "id": "f9bb04ef-78d3-4e0f-9ed1-59a961a0663e" + }, + "outputs": [], + "source": [ + "#Uncomment and run this if you want to see the extracted requriements in json format.\n", + "#get_requirements(\"reqdoc.docx\")" + ] + }, + { + "cell_type": "markdown", + "id": "1fe8618c-1dfe-4030-bad8-405731294c93", + "metadata": { + "id": "1fe8618c-1dfe-4030-bad8-405731294c93" + }, + "source": [ + "### Next, we will make another call to gpt-4o-mini" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "db2c1eb3-7740-43a4-9c0b-37b7e70c739b", + "metadata": { + "id": "db2c1eb3-7740-43a4-9c0b-37b7e70c739b" + }, + "outputs": [], + "source": [ + "#Set up system prompt to ask for test cases in table format\n", + "\n", + "system_prompt = \"You are an assitant that receives a list of functional and non functional requirements in JSON format. You are the expert in generating unit test cases for each requirement. \\\n", + "You will create as many different test cases as needed for each requirement and produce a result in a table. Order the table by requirement No. Provide clear details on test case pass criteria. \\\n", + "The table will contain the following columns. \\\n", + "1.S No\\\n", + "2.Requirement No\\\n", + "3.Requirement Description\\\n", + "4.Test Case ID\\\n", + "5.Test case summary\\\n", + "6.Test case description\\\n", + "7.Success criteria \\n\"\n", + "system_prompt += \"If you are provided with an empty list, ask for a proper requirement doc\\n\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c4cd2bdf-e1bd-43ff-85fa-760ba39ed8c5", + "metadata": { + "id": "c4cd2bdf-e1bd-43ff-85fa-760ba39ed8c5" + }, + "outputs": [], + "source": [ + "# Set up user prompt passing in the req doc file. This in turn will call the get_requirements function, which will make a call to chatgpt.\n", + "\n", + "def get_testcase_user_prompt(reqdoc):\n", + " user_prompt = \"You are looking at the following list of requirements. \\n\"\n", + " user_prompt += f\"{get_requirements(reqdoc)}\\n\"\n", + " user_prompt += \"Prepare unit test cases for each of these requirements in a table and send that table as response. \\n\"\n", + " user_prompt += user_prompt[:25000]\n", + " return user_prompt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59d859e2-e5bb-4bd6-ab59-5ad967d5d2e0", + "metadata": { + "id": "59d859e2-e5bb-4bd6-ab59-5ad967d5d2e0" + }, + "outputs": [], + "source": [ + "#This is the 2nd call to chatgpt to get test cases. display(Markdown) will take care of producing a neatly formatted table output.\n", + "def create_testcase_doc(reqdoc):\n", + " stream = openai.chat.completions.create(\n", + " model=MODEL,\n", + " messages=[\n", + " {\"role\": \"system\", \"content\": system_prompt},\n", + " {\"role\": \"user\", \"content\": get_testcase_user_prompt(reqdoc)}\n", + " ],\n", + " stream=True\n", + " )\n", + " response = \"\"\n", + " display_handle = display(Markdown(\"\"), display_id=True)\n", + " for chunk in stream:\n", + " response += chunk.choices[0].delta.content or ''\n", + " response = response.replace(\"```\",\"\").replace(\"markdown\", \"\")\n", + " update_display(Markdown(response), display_id=display_handle.display_id)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0612d662-7047-4620-aa1c-2eb1c3d715cb", + "metadata": { + "id": "0612d662-7047-4620-aa1c-2eb1c3d715cb" + }, + "outputs": [], + "source": [ + "#The final piece of code. Provide the uploaded requirements filename below.\n", + "file_path = r\"reqdoc.docx\"\n", + "#print(file_path)\n", + "create_testcase_doc(file_path)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "82ae4371-22dd-4f2a-97c9-a70e0232a0aa", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}