테스트의 중요성은 저번 스프링 강의시간에 충분히 느꼈습니다. 하지만, 역시 귀차니즘 때문에 잘 안만들게 되는 게 테스트인 듯 합니다. 하지만, 한번 만들어놓으면 이래저래 매우 유용한 것이 테스트죠.

다운로드는 여기서....-_-


Java에서는 Junit이라는 것이 있는데, 4버전에서는 Annotation(@)을 이용해서 쉽게 테스트를 만들곤 했는데요. Flex에서도 비슷한 기법을 이용합니다. 메타데이터를 위에다가 붙여서-_- 손쉽게 테스트를 만들 수 있습니다.
[code][Test]
public function testMyTest():void
{
}[/code]
와....Flash Builder를 보면 Java를 많이 따라한 것을 볼 수 있습니다. 예전엔 폴더생성으로만 만들 수 있었던 패키지가 직접적인 패키지 생성메뉴를 만들어서 Package Explorer에서 패키지형태로 볼 수 있습니다.
암튼, 자바와 닮아가는 듯-_-

1. 간단한 프로젝트 생성
Flex Project하나 생성.

2. 서비스 클래스 생성
덧셈 뺄셈 클래스하나 작성
com.mudchobo.test패키지의 Calc클래스 생성
Calc.as
[code]package com.mudchobo.test
{
    public class Calc
    {
        public function Calc()
        {
        }
       
        public function addition(a:Number, b:Number):Number
        {
            return a + b;
        }
       
        public function subtraction(a:Number, b:Number):Number
        {
            return a - b;   
        }
    }
}[/code]

3. 테스트 생성
New -> Test Case Class -> New FlexUnit 4 test선택. Name은 CalcTest로하고 Finish.
CalcTest.as
[code]package flexUnitTests
{
    import com.mudchobo.test.Calc;
   
    import flexunit.framework.Assert;

    public class CalcTest
    {
        private var calc:Calc;
       
        public function CalcTest()
        {
        }
       
        [Before]
        public function before():void
        {
            calc = new Calc();   
        }
       
        [Test]
        public function testAddition():void
        {
            var result:Number = calc.addition(50, 50);
            Assert.assertEquals(result, 100);
        }
       
        [Test]
        public function testSubtraction():void
        {
            var result:Number = calc.subtraction(50, 50);
            Assert.assertEquals(result, 0);
        }
    }
}[/code]
여기까지 작성하면 FlexUnitCompiler.mxml이라는 파일이 자동으로 생겼을겁니다. 이건 건드리지 않습니다. 검색해보니 이전방식으로 core생성해서 UIListener를 넣어서 하려고했는데, 이거 그렇게 하는게 아니더군요-_-
심지어 UIListener클래스는 없습니다-_-

4. 테스트 실행
테스트 실행은 package explorer에서 테스트클래스의 오른쪽 마우스버튼을 누르면 "Execute FlexUnit Tests"라는 메뉴가 있습니다. 그걸 선택하면 테스트가 됩니다. FlexUnitApplication.mxml파일도 같이 생기는군요.
테스트단축키는 Alt + Shift + E, F입니다....-_- 해당 편집파일에서 누르면 됩니다.
사용자 삽입 이미지
테스트 결과는 Junit처럼 이렇게 보여줍니다.
사용자 삽입 이미지
Junit이랑 똑같네.

5. 테스트 Suite 생성
이건 테스트를 다 모아서 실행하는 건데, 통합테스트를 할 때 사용하는 듯-_-
New -> Test Suite Class -> New FlesxxUnit4 test 하면 include할 테스트를 패키지에서 선택할 수 있습니다. 선택 후 Finish.
SuiteTest.as
[code]package flexUnitTests
{
    import flexUnitTests.CalcSecondTest;
    import flexUnitTests.CalcTest;
   
    [Suite]
    [RunWith("org.flexunit.runners.Suite")]
    public class SuiteTest
    {
       
        public var test1:flexUnitTests.CalcSecondTest;
        public var test2:flexUnitTests.CalcTest;
    }
}[/code]
그냥 저렇게 선언해두고, 오른쪽버튼 눌러서 "Execute FlexUnit Tests" or 알트 + 쉬프트 + E, F하면 통합테스트를 합니다.

6. 그외의 기능
저도 더 써봐야 알 것 같은데, Flex는 이벤트기반이다보니 Async와 UI구조가 많은데요. Async구조도 손쉽게 테스트를 할 수 있습니다.
[code][Test(async,ui)][/code]
이런식으로 하면 될 듯 한데, 안해봐서 잘 모르겠네요-_-

참고자료
http://www.insideria.com/2009/05/flashbuilder4-will-support-fle.html
http://balajisridhar.wordpress.com/2009/10/05/flexunit-integration-in-flash-builders-new-awatar-in-beta2/
 
Posted by 머드초보
,
 
다운로드는 여기서....-_- adobe.com 사이트에 가입하셔야 합니다.

BlazeDS버전이 4.X대여야 잘 됩니다. 3.X대면 안되더군요.
그리고 BlazeDS버전이 4.x의 Beta1버전이 있는데, 이걸로 하면 요런 에러가 뜹니다.
ERROR : XML parse error : Error on line 1 of document : cvc-elt.1: Cannot find the declaration of element 'model'. Nested exception: cvc-elt.1: Cannot find the declaration of element 'model'.>$2
그래서 전 Night Build중에 4.0.0.11030버전을 사용해서 하니 되더군요.
다운로드는 여기서 http://opensource.adobe.com/wiki/display/blazeds/download+blazeds+trunk

제 환경은 Eclipse 3.5, Flash Builder 4 Beta 2, JDK 1.6.0 U 16입니다.
플러그인으로 못깐 이유가 기존의 Flex Builder 3가 플러그인으로 깔려있는데, 왠지 꼬일 것 같아서(새가슴 ㄷㄷ)-_-

우선 blazeds.war파일을 Eclipse에서 import.
web.xml을 보면 이상한 Servlet이 하나 더 생겼는데요. RDSDispatchServlet.
이거 풀고, 인증부분을 false로 바꾸면 됩니다. 자체적으로 할 수 있는 인증이 생긴 것 같은데, 이건 더 해봐야 알겠네요.
web.xml
[code]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

    <display-name>BlazeDS</display-name>
    <description>BlazeDS Application</description>

    <!-- Http Flex Session attribute and binding listener support -->
    <listener>
        <listener-class>flex.messaging.HttpFlexSession</listener-class>
    </listener>

    <!-- MessageBroker Servlet -->
    <servlet>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <display-name>MessageBrokerServlet</display-name>
        <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
        <init-param>
            <param-name>services.configuration.file</param-name>
            <param-value>/WEB-INF/flex/services-config.xml</param-value>
       </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
   
<!-- begin rds -->
    <servlet>
        <servlet-name>RDSDispatchServlet</servlet-name>
        <display-name>RDSDispatchServlet</display-name>
        <servlet-class>flex.rds.server.servlet.FrontEndServlet</servlet-class>
        <init-param>
            <param-name>useAppserverSecurity</param-name>
            <param-value>false</param-value>
        </init-param>       
        <load-on-startup>10</load-on-startup>
    </servlet>

    <servlet-mapping id="RDS_DISPATCH_MAPPING">
        <servlet-name>RDSDispatchServlet</servlet-name>
        <url-pattern>/CFIDE/main/ide.cfm</url-pattern>
    </servlet-mapping>
<!-- end rds -->

    <servlet-mapping>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <url-pattern>/messagebroker/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
    </welcome-file-list>
</web-app>[/code]
테스트 클래스를 하나 만듭니다.
Test.java
[code]package com.mudchobo.test;

public class TestService {

    public String sayHello(String name)
    {
        return "Hello! " + name;
    }
}[/code]
remoting-config.xml에 destination을 추가.
remoting-config.xml
[code]<destination id="test">
    <properties>
          <source>com.mudchobo.test.TestService</source>
          <scope>application</scope>
     </properties>
     <adapter ref="java-object" />
</destination>[/code]
서버를 이제 작동을 시켜서 띄워둡니다.

이제 Flash Builder로...

프로젝트 생성 -> 타입은 Web, Server type은 J2EE(BlazeDS)
Server location은 Root Folder는 해당 blazeds임포트한 폴더에 있는 WebContent.
Root URL은 http://localhost:8080/blazeds
Context root는 blazeds
Validate Configuration하면 왜 안되지...-_- 암튼 그냥 Finish를 누릅니다-_-

맨 하단에 Data/Services 탭이 있는데, 거기서 Connect to Data/Service.. 클릭.
BlazeDS선택, destionation으로 설정한 test가 하나 보일꺼임. 선택 Finish.
그럼 해당 Destination에 있는 함수인 sayHello가 보이는군요. 사용해봅시다.
여러가지 기능이 있는데요. 저도 잘 몰라서 많이 안해봤는데, 우선 기존에 삽질을 덜어주기 위한 많은 기능을 넣은 것 같습니다. 테스트도 할 수 있고, 자동으로 remoteObject코드도 만들어주고, 뭐 그런 것 같습니다.
Form도 만들어주네요-_-

Test Opeartion을 했더니 파라메터를 던지니 Response value로 나오네요.
사용자 삽입 이미지
버튼 클릭 시 데이터를 요청하는 걸 만들기 위해 Design모드로 변경.
Button과 TextInput, 결과 Label을 하나 추가.
button은 id를 btn, TextInput은 input. button에 오른쪽버튼 누르면 generate Service Call클릭.
그러면 자동으로 click핸들러 함수 만들어지고, sayHello함수 파라메터만 넣으면 되는데, 여기에는 input.text를 넣으면 끝.
Label에는 text에다가 sayHelloResult.lastResult를 바인딩.

DataTest.mxml
[code]<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768" xmlns:test="services.test.*">
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;

            protected function btn_clickHandler(event:MouseEvent):void
            {
                sayHelloResult.token = test.sayHello(input.text);
            }
        ]]>
    </fx:Script>
    <fx:Declarations>
        <s:CallResponder id="sayHelloResult"/>
        <test:Test id="test" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:Button x="248" y="245" label="Button" click="btn_clickHandler(event)" id="btn"/>
    <s:TextInput x="223" y="215" id="input"/>
    <s:Label x="260" y="274" text="{sayHelloResult.lastResult}"/>
   
</s:Application>
[/code]
이런 코드가 됨. 개판임-_-
사용자 삽입 이미지

PS. 자동으로 다 해줘서 좋긴 한데...왠지 익숙하지 않은 코드가.....

참고자료
http://sujitreddyg.wordpress.com/2009/06/01/building-flex-application-for-blazeds-remoting-service-using-flash-builder-4/
 
Posted by 머드초보
,
 
아.....지름신이 강림하셔서 질러버렸습니다.
예전에 HCS-100이라는 것을 사용했었는데, 세탁기에 돌려버리는 바람에 운명을 하셨죠-_-
http://mudchobo.tomeii.com/tt/101

그러다가 한동안 그냥 이어폰으로 듣다가 블루투스가 사고 싶다는 생각이 들어서 막 알아보던 중에 알게된 BackBeat903! 우선 크지 않고, 작은 사이즈의 블루투스이며 헤드셋형태이지만, 이어폰부분과 연결된 부분이 선이여서 헤드셋같지 않은! 근데 가격이 좀 비싸서 망설였지만, 망설임도 잠시뿐 그냥 질러버렸습니다-_-

사용자 삽입 이미지
저렇게 생겼습니다. 음 직접 껴보니깐 가볍고, 낀 것 같지도 않고, 좋습니다^^
사용자 삽입 이미지
내용물은 사실 젠더만 없으면 헤드셋과 충전기 달랑 두개인데, 외국산이다보니, 외국에 맞는 구녕으로된 충전기가 있어서 젠더가 2개 들어있어요. 하나는 또 어느나라에서 쓰는 건지 모르겠네요. 저기 우리나라꺼에 맞는 돼지코 젠더^^

음질
우선 음질은 저번에 쓰던 HCS-100보다는 조금 좋은 듯 한데, 블루투스의 한계는 역시.....OTL...
음질이 조금 지지직 거릴 때도 있긴 하지만, 음질은 나쁘진 않네요^^ 제가 가지고 있는 2만원짜리 사운드매직 이어폰과 비슷한 음질인 듯 합니다(사실...막귀라 잘 모르는 거일지도-_-)

멀티페어링
되는건지 제가 못하는건지 제 핸드폰이 지원을 안하는 건지 정확하게 모르겠습니다. http://cafe.naver.com/plantronics 에서 보면 핸드폰 핸즈프리 연결하면, MP3나 노트북 스테레오로 연결이 된다고 하는데, 제 핸드폰이 이상한게-_- 무조건 스테레오로 연결되네요.
MP3플레이어가 COWON S9인데, 이걸 먼저 연결해버리면, MP3연결할 때 마찬가지로 스테레오로 잡힙니다.
핸드폰이 이상한 듯-_- 하지만, 핸드폰에 블루투스 따위 연결하지 않아도 전화가 잘 안와서 괜찮아요^^(왠지 좀 슬프다....-_- 핸드폰애가ㅠ http://sori.la/nGjOw)

볼륨조절 음악 넘기기 등 버튼 기능
볼륨조절은 매우 특이하게 귀에 꽂힌 이어폰 아래에 달려있습니다. 조그버튼처럼 아래로 레버를 당기면 볼륨이 올라가고 그런 형식입니다. 대신 다음 곡으로 넘기는 것은 조그버튼을 아래로 2초정도 내리고 있어야 넘어갑니다. 버튼을 그냥 왼쪽에도 만들던가....-_- 불편하게 시리.....-_-

사용시간
사용시간은 실제로 써보진 않았지만 7시간으로 써있긴 한데, 뭐 한시간 정도 빼줘서 6시간 정도 가겠죠. 근데 어이없는 건 충전시간이.....3시간인.....-_- 시간당 2시간을 사용할 수 있는 듯-_- 전에 쓰던 HCS-100은 2시간 충전하고 8시간 넘게 쓰는 걸로 알고 있는데....사용시간은 HCS-100이나 다른 블루투스 기기가 훨씬 나은 듯.

그 외에 베이스부스트 기능 및 오픈마이크 기능이 있는데, 베이스부스트 기능은 재생버튼을 2초정도 누르면 나오는데, 그냥 소리가 더 커지는 것(막귀라.....ㅠㅠ)같고, 오픈마이크는 왜있는지 조차 모르겠지만, 음악을 정지하고, 왼쪽에 통화버튼을 누르면 마이크가 보청기가 되어버립니다. 보청기 용도인 듯.....-_-

사용해보니까 뭐 만족하네요. 그냥 음악들을 때 선이 너무 걸리적 거렸어요-_- 출퇴근 시간에 음악을 주로 듣는데, 선으로 부터 프리하고 싶어서......

PS. COWON S9용으로 쓰신다면 블루투스가 DMB는 안됩니다. S9는 안테나가 없고, 이어폰이 안테나용으로 대체하기 때문에 소리는 무조건 이어폰으로 들으셔야합니다.

 
Posted by 머드초보
,
 
문제가 된다면 삭제하겠습니다-_-

전에 WireShark를 이용해서 알송패킷을 캡쳐했을 때 보면 특정주소의 WebService를 요청해서 가져오게 되어있었습니다. http://mudchobo.tomeii.com/tt/434

실제 전송하는 데이터는 MD5값인데, 이게 어떻게 생성되는지 몰라서 구글에서 검색을 하니 어떤 블로그에서 시도한 흔적을 발견했습니다. 거기에 있는 댓글에서 발견했습니다^^
http://dialup.egloos.com/152001

"MP3 파일의 경우 strChecksum 값은 ID3태그등을 제외한 순수 MP3 음악 데이터를 앞에서부터 163840 바이트 읽어서 MD5로 돌린 값입니다. " 라고 친절하게 답변이....-_-

그래서 이렇게 하니까 잘 되더라구요. 아래는 샘플 코드입니다.
필요한 라이브러리는 MD5생성해주는 corelib가 필요합니다.
http://code.google.com/p/as3corelib/
[code]<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    applicationComplete="applicationCompleteHandler()">
    <mx:Script>
        <![CDATA[
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
            import flash.text.engine.ContentElement;
            import mx.messaging.messages.HTTPRequestMessage;
            import mx.rpc.http.HTTPService;
            import com.adobe.crypto.MD5;
            private function applicationCompleteHandler():void
            {
                var fs:FileStream = new FileStream();
                fs.open(new File("C:/Users/mudchobo/Downloads/임재범 - 사랑이라서.mp3"), FileMode.READ);
                var fileSize:int = fs.bytesAvailable;
               
                for (var i:int = 0; i < 500000; i++)
                {
                    if (fs.bytesAvailable >= 3 && fs.readUTFBytes(3) == "ID3")
                    {
                        var sizeByte:ByteArray = new ByteArray();
                       
                        // ID3v2길이구하기
                        fs.position += 3;
                        fs.readBytes(sizeByte, 0, 4);
                        var id3Size:int = sizeByte[0] << 21 | sizeByte[1] << 14 | sizeByte[2] << 7 | sizeByte[3];
                        fs.position = id3Size + 10;
                        break;
                    }
                }
               
                // ID3태그 없는 경우
                if (i == 500000)
                {
                    fs.position = 0;
                }
               
                // 공백있는 ID3태그에 대한 처리
                for (i = 0; i < 50000; i++)
                {
                    if (fs.readUnsignedByte() == 255)
                    {
                        var a:int = fs.readUnsignedByte();
                        if ((a >> 5) == 7)
                        {
                            fs.position += -2;
                            break;
                        }
                    }
                }
               
                // 163840만큼 읽어서 md5생성
                var data:ByteArray = new ByteArray();
                fs.readBytes(data, 0, 163840);
                var md5:String = MD5.hashBytes(data);
               
                // 웹서비스 요청
                var httpService:HTTPService = new HTTPService();
                httpService.method = HTTPRequestMessage.POST_METHOD;
                httpService.contentType = "application/soap+xml";
                httpService.url = "http://lyrics.alsong.co.kr/alsongwebservice/service1.asmx";
                httpService.request = new XML('<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="ALSongWebServer/Service1Soap" xmlns:ns1="ALSongWebServer" xmlns:ns3="ALSongWebServer/Service1Soap12"><SOAP-ENV:Body><ns1:GetLyric5><ns1:stQuery><ns1:strChecksum>' + md5 + '</ns1:strChecksum><ns1:strVersion>2.0 beta2</ns1:strVersion><ns1:strMACAddress>ffffffffffff</ns1:strMACAddress><ns1:strIPAddress>255.255.255.0</ns1:strIPAddress></ns1:stQuery></ns1:GetLyric5></SOAP-ENV:Body></SOAP-ENV:Envelope>');
                httpService.addEventListener(ResultEvent.RESULT, resultHandler);
                httpService.addEventListener(FaultEvent.FAULT, faultHandler);
                httpService.send();
            }
           
            private function resultHandler(event:ResultEvent):void
            {
                trace("싱크가사 = " + event.result.Envelope.Body.GetLyric5Response.GetLyric5Result.strLyric);
            }
           
            private function faultHandler(event:FaultEvent):void
            {
                trace(event.toString());
            }
           
        ]]>
    </mx:Script>
</mx:WindowedApplication>
[/code]
여기서 알송가사에서 제공하는 웹서비스는 WebService인데, HTTPService로 요청한 이유는 wsdl문서가 어디있는지 못찾겠음 ㄷㄷ 그래서 그냥 httpservice로 xml통채로 넘겨버리니-_- 되더라구요 ^^
xml넘길 때 strCheckSum값만 md5구한걸로 넘기면 돼요^^

[code]싱크가사 = [00:00.00]하루 하루 그대만 보여서<br>[00:23.28]매일매일 눈을 가리고 살아<br>[00:31.34]그대 곁을 나조차도 모르게 머물며<br>[00:38.91]메마른 내 가슴이 그댈 잊어버리지 못한 이유는<br>[00:00.00]<br>[00:00.00]<br>[00:49.93]사랑이라서 사랑이라서<br>[00:56.06]두번다시 못볼 사랑이라서<br>[00:00.00]<br>[01:03.32]하늘이 하는 일 돌릴 수 없는 일<br>[01:11.39]이렇게 사는게 힘들면 그녈 보내줄텐데<br>[01:19.51]죽어서 보라고 그래서 보라고<br>[01:26.42]그때라도 사랑한 마음이 남아있게된다면<br>[01:34.53]그때쯤에<br>[00:00.00]<br>[01:42.93]어딜가도 그대만 보여서<br>[01:49.88]매일매일 나를 지우고 살아<br>[01:57.28]한순간도 바람처럼 떠날줄 모르고<br>[02:04.71]죽어도 내가슴이 그댈 떠나보내지 못한 이유는<br>[00:00.00]<br>[02:15.49]사랑이라서 사랑이라서<br>[02:23.68]가슴가득 맺힌 사랑이라서<br>[00:00.00]<br>[02:29.68]하늘이 하는 일 돌릴 수 없는 일<br>[02:37.81]이렇게 사는게 힘들면 그녈 보내줄텐데<br>[02:45.79]죽어서 보라고 그래서 보라고<br>[02:52.51]그때라도 사랑한 마음이 남아있게 된다면<br>[03:00.90]그때쯤에<br>[00:00.00]<br>[03:04.66]간절히 바랬어 너에게 가는일<br>[00:00.00]<br>[03:33.19]하늘이 하는 일 돌릴 수 없는 일<br>[03:41.80]이렇게 사는게 힘들면 그녈 보내줄텐데<br>[03:49.23]죽어서 보라고 그래서 보라고<br>[03:56.56]그때라도 사랑한 마음이 남아있게된다면<br>[04:04.29]그때쯤에<br>[/code]

PS. HTTPService에서 xml전송해서 하는 거 어떻게 하는지 몰랐는데, 그냥 httpservice에 있는 request객체에 xml을 생성해서 넣어주면 된다는....-_-

 
Posted by 머드초보
,
 
뭐가 좋을까 조사중-_-
Trac은 예전에 친구들과 프로젝트를 하면서 사용해봐서 조금 아는데, RedMine이라는 것은 처음들었는데, 여기저기에서 좋다고 많이 추천을 하는 이슈관리시스템인 듯 하네요.
그래서 조금 써보니까 대충 이렇게 비교가 되네요.
RedMind = Trac + @;인 듯 합니다. Trac에 있는 기능은 다 있고, 거기에 차트같은 부가기능도 좀 더 있고, 다양한 Repository를 지원하는 듯합니다. Trac도 뭐 플러그인 깔면 다 할 수 있다곤 하지만, 사람들은 올인원을 좋아하기때문에.....-_-


1. 개발언어
RedMine은 Ruby, Trac은 Python

2. 공통적으로 있는 것
  • 위키시스템 - 둘 다 비슷한 방식으로 제공. 하지만, 편집기가 조금 다른 것 같음(문법).
  • 작업내역 보여주기 - Trac은 Timeline으로 RedMine은 작업내역(Activity)로 존재한다. svn커밋이나 문서나 이슈생성 등을 하게되면 여기에 내역이 남는다.
  • 이슈(티켓) - Trac은 Ticket이고, RedMine은 Issues로 존재. 이것도 비슷하긴 한데, RedMine에서는 이슈마다 현재 작업진행도를 입력할 수 있고, 완료 기간까지 입력이 가능하다. 이 이슈에 대해서 반만 작업되었다면 50%로 업데이트가 가능-_-
  • SVN연동 - Trac은 svn을 자체적으로 생성해서 연동하는 걸로 알고 있는데, RedMine은 뭐 그냥 svn주소만 입력하면 연동이 되는 듯 하다.
  • 다국어지원 - Trac과 RedMine 둘 다 한국어 지원을 한다. 오픈소스프로젝트이기 때문에 사람들이 많이 참여를 해서 쉽게 한글화를 한 것 같다. RedMine에서 가장 눈에 띄는 한글화는 Issues->일감 이다.
  • 로드맵 - 해당프로젝트에 대해서 해당 이슈가 얼마만큼 해결이 되었는지 보여주는 로드맵. 기능은 비슷한 듯.
  • Eclipse MyLyn연동 - 둘 다 연동이 되는 듯. Trac밖에 해보진 않았지만, RedMine도 찾아보니 있음.
  • 소스코드비교 - svn에서 소스코드비교된 것이 화면에 나옴. Trac은 한화면보기 밖에 안되고, Reversion별로 비교를 할 수 없음. RedMine은 두화면보기도 되며, Reversion별 비교를 할 수 있음.
3. RedMine에만 있는 것
  • Gantt Chart - 해야할 이슈가 언제까지 해야하고 해당 프로젝트가 언제 완료해야하는 지 한눈에 알아볼 수 있는 Gantt Chart를 제공한다. 이슈만 제대로 입력한다면 이 차트는 자동으로 작성이 된다.
  • 뉴스 - 뉴스라고 해서 이걸 입력하면 개요부분에 보이게 되는데, 그냥 RedMine에 접속해서 가장 처음에 볼 수 있는 새로운 소식과 같은 기능임.
  • 문서 - Trac같은 경우 문서관리를 그냥 Wiki에서 다 했었는데, 문서라는 메뉴가 따로 있음. 따로 있는 게 더 좋은 듯.
  • 관련파일 - 파일만 따로 올릴 수 있는 기능이 있음.
4. Trac에만 있는 것
  • 상세 권한 설정 - 아무리 찾아봐도 Trac에만 있는 건 이것 하나인 것 같기도....-_- Ticket보고, 수정하고, 생성하는 권한을 상세히 설정할 수 있음. 사실 좀 필요 없는 것 같은데....-_-

스크린샷 RedMine에 있는 소스비교.
사용자 삽입 이미지
스크린샷 RedMine의 Gantt Chart
사용자 삽입 이미지
결론은 RedMine....-_-
 
Posted by 머드초보
,