我已经完成了医生管理系统的登录屏幕和菜单。用户登录并发送到主菜单,根据角色类型,他们在每个子菜单上具有不同的控件。
一切正常,现在该进行测试了。
我从未做过自动化测试-单元,集成或端到端。
据我了解,最好将业务逻辑与表示逻辑分开,并且仅对业务逻辑进行单元测试?
请记住,按钮可见性和消息框是演示逻辑,对吗?并且最适合用于验证功能的手动测试计划?是吗?
我确定我应该对登录是否成功进行单元测试?但是,该方法不依赖数据库吗?那是集成测试吗?
这是我的代码
登录表单
private void btnLogin_Click(object sender, EventArgs e)
{
//Try and open a connection with database and run the code
try
{
//Create new instance of sql connection, pass in the connection string for BayOneSurgerySystem.mdf to connect to database.
SqlConnection conn = new SqlConnection(@"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\davie\Documents\UniWork\Software Engineering\BayOneSurgerySystem1.0\Database\BayOneSystem.mdf;Integrated Security=True;Connect Timeout=30");
//Create new instance of SQlCommand and pass in a query to be called to retrieve table data for username and passwords aswell as the connection object.
SqlCommand cmd = new SqlCommand("SELECT * FROM Users WHERE Username = @username and Password = @password", conn);
//This passes user input into @username and @password
cmd.Parameters.AddWithValue("@username", txtBoxUsername.Text);
cmd.Parameters.AddWithValue("@password", txtBoxPassword.Text);
//Open connection with database
conn.Open();
//Create new instance of dataSet to hold the data retrieved from sql query
DataSet ds = new DataSet();
//Create new instance of DataAdpater to retrieve the data pass in Sql command
SqlDataAdapter da = new SqlDataAdapter(cmd);
//using DataAdapter fill in dataSet wiht data if user input and stored data matches
da.Fill(ds);
//Close the connection now data table is filled with username and password
conn.Close();
//declare bool, true if there is a match with database and user input
bool loginSuccess = (ds.Tables[0].Rows.Count == 1);
//if login success is true then open menu
if (loginSuccess)
{
/*Change state of enum RoleTypes based on result from dataSet Role_ID column.
In UserRole table records are as follows:
Role_ID 1 = PracticeManager
2 = Doctor
3 = Receptionist*/
//Print role_ID to console to check that is been set.
Console.WriteLine(ds.Tables[0].Rows[0]["Role_ID"]);
try
{
//Condition for the switch statement is: check Role_ID from UserRoles table
switch (ds.Tables[0].Rows[0]["Role_ID"])
{
//if the case is that Role_ID for the user logged in is 1 then run the function etc.
case 1:
{
Roles.Role = Roles.RoleType.practiceManager;
Console.WriteLine("Role type changed to " + Roles.Role);
}
break;
case 2:
{
Roles.Role = Roles.RoleType.doctor;
Console.WriteLine("Role type changed to " + Roles.Role);
}
break;
case 3:
{
Roles.Role = Roles.RoleType.receptionist;
Console.WriteLine("Role type changed to " + Roles.Role);
}
break;
default:
break;
}
}//Switch condition cannot be reached then catch exception and print to console.
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.WriteLine("Logged in.");
FrmMenu menu = new FrmMenu();
menu.Show();
this.Hide();
}
else
{
MessageBox.Show("Invalid username or password.", "Error!", MessageBoxButtons.RetryCancel);
Console.WriteLine("Not logged in");
}
}
//If connection cant be opened diplsay error message and catch exception and print to console
catch (Exception ex)
{
Console.WriteLine(ex);
MessageBox.Show("Sorry can't connect");
}
}
}
}
角色类别
public static class Roles
{
/*The RoleType enum is declared here and changed in form login. RoleType is the condition for button visibility
I.e if roletype is doctor, show doctor buttons*/
public static RoleType Role;
public enum RoleType
{
practiceManager,
doctor,
receptionist
}
}
患者表格
//if this is clicked, display yesNo messagebox. If yes, logout.
private void btnLogout_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Are you sure?", "Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
FrmLogin logout = new FrmLogin();
logout.Show();
this.Close();
}
}
private void FrmPatients_Load(object sender, EventArgs e)
{
/*Buttons are visible depending on access level. Permissions are as follows:
* Practice Manager - Patient Records
Doctor - Register Patient, Patient notes
Receptionist - New Patient, Register Patient*/
if (Roles.Role == Roles.RoleType.practiceManager)
{
this.btnNewPatient.Visible = false;
this.btnNotes.Visible = false;
this.btnSignIn.Visible = false;
}
else if (Roles.Role == Roles.RoleType.doctor)
{
this.btnNewPatient.Visible = false;
}
else
{
this.btnNotes.Visible = false;
}
}
//if this is clicked return to main menu
private void pcBxBack_Click(object sender, EventArgs e)
{
FrmMenu menu = new FrmMenu();
this.Close();
menu.Show();
}
}
}
测试课程
[TestClass]
public class LoginTests
{
[TestMethod]
public void Constuctor_NormalData_Login_Is_Successful()
{
//Arrange
//Act
//Assert
}
[TestMethod]
public void Constructor_RoleTypeEnum_RoleType_Changes()
{
//Arrange
//Act
//Assert
}
}
您对自动测试的用途有何建议?
我有一个手动表,其中包含21个测试,用于验证所有消息框,按钮单击事件和按钮可见性。
对于A,我确实需要一些自动化测试。如您所见,我已经具有用于测试角色类型枚举和成功登录的模板,这是我可以看到的仅有的两种显而易见的测试方法。
谢谢!
答案 0 :(得分:2)
在这种情况下,请避免进行单元测试,而要进行端到端测试。
您的问题非常模糊-在堆栈溢出时我们尝试避免这种情况,因为它很难回答。最好的答案将是模糊的。在最坏的情况下,问题将被投票决定结束,而提问者(即您)将失去精力。
话虽如此,我却想去一个模糊的答案。
看看您的btnLogin_Click
方法,我发现您尚未将业务逻辑与用户界面分开。所述方法知道如何连接到数据库以及如何本地查询数据库,并且知道要更新数据库的用户界面,还知道如何登录到控制台。它可能知道更多,但这足以让我向您建议不要进行单元测试。
简而言之,单元测试是一种验证机器外观和性能的齿轮的方法。
您的机器上有Alla嵌齿轮和杠杆以及冲刺和主轴。我并不是说您的代码很糟糕;但是如果您要单元测试,那么您将很难过。
改为进行端到端测试。
Visual Studio有一种方法可以automate applications。 (在解释Visual Studio的功能时,我不知道您是否必须具有特殊的许可证级别,因为Microsoft会“忘记”来描述这一点。
然后是Sikuli。
还有更多。
我不建议上面的那些或其他任何东西,但这必须由您选择。挖掘并测试找到您喜欢的人。许多是F / OSS。
HTH
和快乐的黑客入侵!