ผลต่างระหว่างรุ่นของ "Oop lab/unit testing slick2d"
Jittat (คุย | มีส่วนร่วม) |
Jittat (คุย | มีส่วนร่วม) |
||
แถว 1: | แถว 1: | ||
: ''หน้านี้เป็นส่วนหนึ่งของ [[oop lab]].'' | : ''หน้านี้เป็นส่วนหนึ่งของ [[oop lab]].'' | ||
− | เราต้องการจะเขียน unit test กับโค้ดใน Slick2D อย่างไรก็ตามโค้ดส่วนของ Entity ของเรานั้นมักมีส่วนการแสดงผลอยู่ด้วย และส่วนเหล่านี้โดยมากจะทำงานไม่ได้ใน unit test หรือไม่ก็ทำให้การเตรียมการต่าง ๆ มีปัญหา | + | เราต้องการจะเขียน unit test กับโค้ดใน Slick2D อย่างไรก็ตามโค้ดส่วนของ Entity ของเรานั้นมักมีส่วนการแสดงผลอยู่ด้วย และส่วนเหล่านี้โดยมากจะทำงานไม่ได้ใน unit test หรือไม่ก็ทำให้การเตรียมการต่าง ๆ มีปัญหา |
+ | |||
+ | เพื่อเพิ่มความเข้าใจ เราจะยกตัวอย่างจากโค้ด BulletGame แต่เราจะเพิ่มให้คลาส Bullet ใช้รูปลูกกระสุน แทนที่จะเป็นการวาดรูปธรรมดา | ||
+ | |||
+ | == Bullet ที่แสดงโดยการวาดรูป == | ||
+ | |||
+ | เพื่อเป็นการทดลอง เราจะใช้รูป ship จาก ship เกมในการแสดงกระสุน เมื่อรันแล้วอาจจะมีหน้าตาแบบนี้ | ||
+ | |||
+ | [[Image:Ship-bullets.png]] | ||
+ | |||
+ | เราจะคัดลอกไฟล์ ship.png มาใส่ในไดเร็กทอรี res และเพิ่ม field image, แก้ constructor, และปรับเมท็อด render ในคลาส Bullet ดังนี้ | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
+ | public class Bullet implements Entity { | ||
+ | //... | ||
+ | protected Image image; | ||
+ | |||
public Bullet(float x, float y) { | public Bullet(float x, float y) { | ||
try { | try { | ||
แถว 12: | แถว 26: | ||
this.setXY(x,y); | this.setXY(x,y); | ||
} | } | ||
+ | |||
+ | public void render(Graphics g) { | ||
+ | image.draw(getX(), getY()); | ||
+ | //g.fillOval(getX(), getY(), BULLET_SIZE, BULLET_SIZE); --- this is removed line | ||
+ | } | ||
+ | //... | ||
+ | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{กล่องเทา|หมายเหตุ: block try-catch นั้นอาจจะดูรกรุงรัง แต่จำเป็นเพราะว่าการเปิด image ใหม่นั้น อาจจะเกิด exception ขึ้นได้}} | {{กล่องเทา|หมายเหตุ: block try-catch นั้นอาจจะดูรกรุงรัง แต่จำเป็นเพราะว่าการเปิด image ใหม่นั้น อาจจะเกิด exception ขึ้นได้}} | ||
+ | |||
+ | == ทดลอง unit test == | ||
และในโค้ด unit test ของเรา เป็นดังนี้ | และในโค้ด unit test ของเรา เป็นดังนี้ |
รุ่นแก้ไขเมื่อ 01:18, 22 กันยายน 2557
- หน้านี้เป็นส่วนหนึ่งของ oop lab.
เราต้องการจะเขียน unit test กับโค้ดใน Slick2D อย่างไรก็ตามโค้ดส่วนของ Entity ของเรานั้นมักมีส่วนการแสดงผลอยู่ด้วย และส่วนเหล่านี้โดยมากจะทำงานไม่ได้ใน unit test หรือไม่ก็ทำให้การเตรียมการต่าง ๆ มีปัญหา
เพื่อเพิ่มความเข้าใจ เราจะยกตัวอย่างจากโค้ด BulletGame แต่เราจะเพิ่มให้คลาส Bullet ใช้รูปลูกกระสุน แทนที่จะเป็นการวาดรูปธรรมดา
เนื้อหา
Bullet ที่แสดงโดยการวาดรูป
เพื่อเป็นการทดลอง เราจะใช้รูป ship จาก ship เกมในการแสดงกระสุน เมื่อรันแล้วอาจจะมีหน้าตาแบบนี้
เราจะคัดลอกไฟล์ ship.png มาใส่ในไดเร็กทอรี res และเพิ่ม field image, แก้ constructor, และปรับเมท็อด render ในคลาส Bullet ดังนี้
public class Bullet implements Entity {
//...
protected Image image;
public Bullet(float x, float y) {
try {
image = new Image("res/ship.png"); // this line is problematic.
} catch (SlickException e) {
e.printStackTrace();
}
this.setXY(x,y);
}
public void render(Graphics g) {
image.draw(getX(), getY());
//g.fillOval(getX(), getY(), BULLET_SIZE, BULLET_SIZE); --- this is removed line
}
//...
}
หมายเหตุ: block try-catch นั้นอาจจะดูรกรุงรัง แต่จำเป็นเพราะว่าการเปิด image ใหม่นั้น อาจจะเกิด exception ขึ้นได้
ทดลอง unit test
และในโค้ด unit test ของเรา เป็นดังนี้
public class BulletTest {
@Test
public void test() {
Bullet b = new Bullet(10,20);
}
}
เมื่อเราเรียกให้ unit test ทำงาน เราจะพบ error ดังนี้
java.lang.RuntimeException: No OpenGL context found in the current thread. at org.lwjgl.opengl.GLContext.getCapabilities(GLContext.java:124) at org.lwjgl.opengl.GL11.glGetError(GL11.java:1289) at org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer.glGetError(ImmediateModeOGLRenderer.java:384) at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:249) at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.java:187) ... at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
เพราะว่าจะเปิด Image ได้นั้น โปรแกรมของเราจะต้องมีการจัดการเปิดหน้าต่างและจัดการเกี่ยวกับ OpenGL ก่อน ซึ่งในส่วนนี้ เรามักจะไม่ดำเนินการใน Unit test
การเขียนโปรแกรมให้ test ได้ง่ายนั้น เป็นทักษะแบบหนึ่งที่มีประโยชน์มาก และโดยมาก ความพยายามที่จะทำให้โปรแกรม test ได้ง่าย จะทำให้เราได้รับโค้ดที่ดีมีคุณภาพด้วย
ในส่วนนี้เราจะทดลองเพิ่มเมท็อด distanceTo(float x, float y) ให้กับคลาส Bullet เพื่อทดลองการทำ unit test
วิธีที่ 1: สร้าง Image ยามต้องการ
เพื่อให้โค้ด test ได้ โค้ดทุกส่วนที่เกี่ยวข้องกับการทำงานทั่วไป (ที่ไม่เกี่ยวกับการแสดงผล) จะต้องไม่มีการจัดการเกี่ยวกับการแสดงผลเลย และจะมีโค้ดเกี่ยวกับการแสดงผลเมื่อจำเป็น เช่นเมื่อมีการเรียก render แล้ว
เราจะแก้ constructor ของเราดังนี้
public Bullet(float x, float y) {
image = null;
this.setXY(x,y);
}